I am currently stuck with reading form data. Below is my controller code.
using System.Net;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using Rehub.Models;
using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment;
namespace Rehub_v1._0.Areas.Admin.Controllers
{
public class TestController : Controller
{
private IHostingEnvironment Environment;
public TestController()
{
}
[HttpPost]
public async Task<HttpResponseMessage> Post()
{
string path = Path.Combine(this.Environment.WebRootPath, "~/App_Data");
var provider = new MultipartFormDataStreamProvider(path);
await Request.Content.ReadAsMultipartAsync(provider);
var email = new SendGridEmail
{
Dkim = provider.FormData.GetValues("dkim").FirstOrDefault(),
To = provider.FormData.GetValues("to").FirstOrDefault(),
Html = provider.FormData.GetValues("html").FirstOrDefault(),
From = provider.FormData.GetValues("from").FirstOrDefault(),
Text = provider.FormData.GetValues("text").FirstOrDefault(),
SenderIp = provider.FormData.GetValues("sender_ip").FirstOrDefault(),
Envelope = provider.FormData.GetValues("envelope").FirstOrDefault(),
Attachments = int.Parse(provider.FormData.GetValues("attachments").FirstOrDefault()),
Subject = provider.FormData.GetValues("subject").FirstOrDefault(),
Charsets = provider.FormData.GetValues("charsets").FirstOrDefault(),
Spf = provider.FormData.GetValues("spf").FirstOrDefault()
};
// The email is now stored in the email variable
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
}
I get the error on await Request.Content.ReadAsMultipartAsync(provider):
"CS1061 C# ‘HttpRequest’ does not contain a definition for ‘Content’ and no accessible extension method ‘Content’ accepting a first argument of type ‘HttpRequest’ could be found"
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using pdrake.Models;
namespace pdrake.Controllers
{
public class MovieApiController : Controller
{
private const string baseUrl = "https://api.themoviedb.org/3/discover/movie?api_key=my_key";
public List<Movie> Movies { get; set; }
public async Task<AcceptedResult> GetMovies()
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(baseUrl);
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
Movies = JsonConvert.DeserializeObject<List<Movie>>(Json(baseUrl));
return View(Movies);
}
}
}
I've been struggling all day trying to figure out how to transfer the Json from baseUrl to the list Movies which can be looped through with a foreach loop.
Change your using block to the following,
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(baseUrl);
string data = await response.Content.ReadAsStringAsync();
return View(JsonConvert.DeserializeObject<List<Movie>>(data));
}
This will call the baseUrl along with receiving the text / content from the response. once you have the data, you can deserialize that to your List<Movie> object and return it as a View.
I'm working on a new application where I need to use Clockify's API. When I make my test application for a proof of concept, I notice that I'm getting a 401 error as a response to using one of their base functions, get clients by work space. Am I missing something with the authentication? Is there a setting I need to allow on my profile? The error I'm getting is: System.Net.WebException: 'The remote server returned an error: (401) Unauthorized.' Thanks.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace Api
{
public class ApiHelper
{
public static HttpClient ApiClient { get; set; } = new HttpClient();
public static void InitializeClient(string username, string password)
{
ApiClient = new HttpClient();
ApiClient.BaseAddress = new Uri("https://api.clockify.me/api/");
ApiClient.DefaultRequestHeaders.Accept.Clear();
ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public static void GetClientsFromWorkspace(string workspace)
{
ApiClient.DefaultRequestHeaders.Add("X-Api-Key", "*********");
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.clockify.me/api/workspaces/" + workspace + "/clients");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "GET";
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
}
}
}
You’re setting the api key header on the ApiClient but then making your request with a newly createdHttpWebRequest which doesn’t then have the required api key header.
You should either make your request using the ApiClient or add the X-Api-Key header to theHttpWebRequest as follows:
httpWebRequest.Headers.Add(“X-Api-Key”, “********”)
i am trying an api and receive data. i got the api username and password but when im trying to connect i get an unauthorized request. i thing something is wrong with my request-header -authentication.
here is my code:
using ApiData;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace GetDataFromApi
{
class Program
{
static void Main(string[] args)
{
string uri1 = "https://api.intrinio.com/companies?ticker=AAPL";
ConnectToApi newapi = new ConnectToApi("username", "password", uri1);
Console.ReadLine();
}
public class ConnectToApi
{
public string Username { get; set; }
public string Password { get; set; }
public string Request_url { get; set; }
public ConnectToApi(string username, string password, string url)
{
this.Username = username;
this.Password = password;
this.Request_url = url;
GetAPIToken(Username, Password, Request_url);
}
private static async void GetAPIToken(string userName, string password, string apiBaseUri)
{
try
{
using (var client = new HttpClient())
{
//setup client
client.BaseAddress = new Uri(apiBaseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{userName}:{password}")));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//send request
var responseMessage = await client.GetStringAsync(apiBaseUri);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
}
if you have any comments on my code i would love to hear it.
thanks.
lidor
This might Help
you need to get RestSharp for this to work
var client = new RestClient("https://api.intrinio.com/companies?ticker=AAPL");
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("authorization", "Basic MGU0NWIxZmIwZDFlMGNkMDEzY2Y2Y2I5MmRlNjk2N2M6MjNjYjM3OTQ3ZmFmMjQ0OWI1MWRjMWQ1NGU2ZGE1Zjc=");
IRestResponse response = client.Execute(request);
and you can try to convert it to an object by
try
{
dynamic x = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(response.Content, new Newtonsoft.Json.JsonSerializerSettings() { NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore });
return x;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return null;
}
and i do recommend of using http://json2csharp.com/
to create your C# Object
More Information
To get the Value that is used for authorization you can use this method
public static string Base64Encode(string key)
{
var value = System.Text.Encoding.UTF8.GetBytes(key);
return System.Convert.ToBase64String(value);
}
to get the exact value make sure the username and password are concatenated, (username first , password second) and then passed to the method
I am trying to create an SSO like solution between 2 .Net applications
.Net app 1 has a custom token generator and endpoints to validate tokens that returns user information.
.Net application 2 is protected using Owin and was a typical standalone app and a user would directly login using a password and username.
I created (based on Passion for Coding Blog and Github) a custom Owin provider that would look for a token either in a Authorization header or as a query parameter from a link that a user would click a link from .Net App 1 and send to the .Net App 2 the token in the query string as at GET (I know this is not secure we are eventually going to use OpenID for what it’s worth we just need this for a demo). I am able to get the token validate it and create an Identity and authenticate I just cant get the provider to create a .Net Auth Cookie so that subsequent requests are authenticated and not given a 401 error.
Handler File:
using Microsoft.Owin.Infrastructure;
using Microsoft.Owin.Logging;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace SomeOAuth
{
// Created by the factory in the someAuthenticationMiddleware class.
class SomeAuthenticationHandler : AuthenticationHandler<SomeAuthenticationOptions>
{
private const string HandledResponse = "HandledResponse";
private readonly ILogger _logger;
private readonly string _challenge;
/// <summary>
/// Creates a new OpenIdConnectAuthenticationHandler
/// </summary>
/// <param name="logger"></param>
public SomeAuthenticationHandler(ILogger logger, string challenge)
{
_logger = logger;
_challenge = challenge;
}
protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()
{
// ASP.Net Identity requires the NameIdentitifer field to be set or it won't
// accept the external login (AuthenticationManagerExtensions.GetExternalLoginInfo)
string requestToken = null;
string authorization = Request.Headers.Get("Authorization");
if (!string.IsNullOrEmpty(authorization))
{
if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
{
requestToken = authorization.Substring("Bearer ".Length).Trim();
}
}
if (string.IsNullOrEmpty(requestToken))
{
string accessTokenParam = Request.Query.Get("access_token");
if (!string.IsNullOrEmpty(accessTokenParam))
{
requestToken = accessTokenParam;
}
}
if (!string.IsNullOrEmpty(requestToken))
{
using (var client = new HttpClient())
{
try
{
var request = new HttpRequestMessage(HttpMethod.Post, "https://testserver/API/Auth/Authenticate");
var s = new StringContent("{\"oauthtoken\":\"" + requestToken + "\"}", Encoding.UTF8, "application/json");
// var ts = s.ToString();
request.Content = new StringContent("{\"oauthtoken\":\"" + requestToken + "\"}", Encoding.UTF8, "application/json");
System.Diagnostics.Debug.WriteLine("Request:");
System.Diagnostics.Debug.WriteLine(request.ToString());
if (request.Content != null)
{
System.Diagnostics.Debug.WriteLine(await request.Content.ReadAsStringAsync());
}
System.Diagnostics.Debug.WriteLine("");
var response = await client.SendAsync(request);
if (response.StatusCode != HttpStatusCode.OK)
{
return null;
}
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var userId = payload.Value<string>("username");
//need to get the useid of the user as well as the name and role
var identity = new ClaimsIdentity("Some");
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "fakeuser", null, "Some"));
/*
identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName + " " + user.LastName));
identity.AddClaim(new Claim(ClaimTypes.Email, user.ContactInfo.Email));
identity.AddClaim(new Claim(ClaimTypes.Sid, user.Guid.ToString()));
*/
identity.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "Some"));
AuthenticationProperties properties = CreateProperties("fakeusername", "");
var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
return ticket;
}
catch (Exception e)
{
Console.WriteLine("asdf e = " + e.Message);
}
return null;
}
}
else
{
return null;
}
}
/// <summary>
/// Handles SignIn
/// </summary>
/// <returns></returns>
protected override Task ApplyResponseChallengeAsync()
{
if (Response.StatusCode == 401)
{
AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);
if (challenge == null)
{
return null;
}
}
return Task.FromResult<object>(null);
}
public override Task<bool> InvokeAsync()
{
return InvokeReplyPathAsync();
}
private async Task<bool> InvokeReplyPathAsync()
{
AuthenticationTicket ticket = await AuthenticateAsync();
if (ticket != null)
{
string value;
if (ticket.Properties.Dictionary.TryGetValue(HandledResponse, out value) && value == "true")
{
return true;
}
if (ticket.Identity != null)
{
Request.Context.Authentication.SignIn(ticket.Properties, ticket.Identity);
}
// Redirect back to the original secured resource, if any.
if (!string.IsNullOrWhiteSpace(ticket.Properties.RedirectUri))
{
Response.Redirect(ticket.Properties.RedirectUri);
return true;
}
}
return false;
}
private static AuthenticationTicket GetHandledResponseTicket()
{
return new AuthenticationTicket(null, new AuthenticationProperties(new Dictionary<string, string>() { { HandledResponse, "true" } }));
}
public AuthenticationProperties CreateProperties(string userName, string Roles)
{
IDictionary<string, string> data = new Dictionary<string, string>
{
{ "userName", userName },
{"roles",Roles}
};
return new AuthenticationProperties(data);
}
}
}
Middleware file:
using Microsoft.Owin;
using Microsoft.Owin.Security.Infrastructure;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataProtection;
using Microsoft.Owin.Security.DataHandler;
using Microsoft.Owin.Logging;
namespace SomeOAuth
{
// One instance is created when the application starts.
public class SomeeAuthenticationMiddleware : AuthenticationMiddleware<SomeAuthenticationOptions>
{
private readonly ILogger _logger;
private readonly string _challenge = "Bearer";
public SomeAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, SomeAuthenticationOptions options)
: base(next, options)
{
_logger = app.CreateLogger<SomeAuthenticationMiddleware>();
}
// Called for each request, to create a handler for each request.
protected override AuthenticationHandler<SomeAuthenticationOptions> CreateHandler()
{
return new SomeAuthenticationHandler(_logger, _challenge);
}
}
}
Options file:
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SomeOAuth
{
public class SomeAuthenticationOptions : AuthenticationOptions
{
public SomeAuthenticationOptions(string userName, string userId)
: base(OAuthDefaults.AuthenticationType)
{
UserName = userName;
UserId = userId;
}
public string Challenge { get; set; }
public string UserName { get; set; }
public string UserId { get; set; }
}
}
Extensions File:
using Microsoft.Owin.Extensions;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SomeOAuth
{
public static class SomeAuthenticationExtensions
{
public static IAppBuilder UseSomeeAuthentication(this IAppBuilder app, SomeAuthenticationOptions options)
{
if (app == null)
{
throw new ArgumentNullException("app");
}
app.Use(typeof(SomeAuthenticationMiddleware), app, options);
app.UseStageMarker(PipelineStage.Authenticate);
return app;
}
}
}
Startup File
using System;
using CoreLX.Palms.VS.Web.Services;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin.Security.Providers.OpenID;
using Microsoft.Owin.Security.OAuth;
using Owin;
using SomeOAuth;
using CoreLX.Palms.LS.Web.Common.Models.User;
namespace CoreLX.Palms.VS.Web
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager> (ApplicationSignInManager.Create);
//app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
//{
// AccessTokenProvider = new SomeTokenProvider(),
// Provider = new SomeOAuthBearerAuthenticationProvider("access_token")
//});
app.UseSomeAuthentication(new SomeAuthenticationOptions("testuser", "9"));
// Use a cookie to temp store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(
new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
ExpireTimeSpan = new TimeSpan(0, 3, 0, 0),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)),
OnApplyRedirect = ctx =>
{
// don't redirect to login page for webapi/ajax requests
// http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/
if (!IsWebApiRequest(ctx.Request))
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
app.UseOpenIDAuthentication("http://me.yahoo.com/", "Yahoo");
}
private static bool IsWebApiRequest(IOwinRequest request)
{
// hack for check if it's webapi requesr
if (request.Path.StartsWithSegments(new PathString("/api")))
{
return true;
}
// checks if it's ajax request
IReadableStringCollection query = request.Query;
if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
{
return true;
}
IHeaderDictionary headers = request.Headers;
return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest"));
}
}
}
I have also tried to just use the custom providers for the standard provided
OAuthBearerAuthenticationProvider
Here is the code for the plugins/providers that I tried I don't have a preference as long as there are no 401 errors:
Provider
using Microsoft.Owin.Security.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SomeOAuth
{
public class SomeOAuthBearerAuthenticationProvider : IOAuthBearerAuthenticationProvider
{
readonly string _parameterName;
public SomeOAuthBearerAuthenticationProvider(string parameterName)
{
_parameterName = parameterName;
}
public Task ApplyChallenge(OAuthChallengeContext context)
{
return Task.FromResult<object>(null);
}
public Task RequestToken(OAuthRequestTokenContext context)
{
string token = context.Token;
if(string.IsNullOrEmpty(token) && !string.IsNullOrEmpty(_parameterName))
{
token = context.Request.Query.Get(_parameterName);
}
if (!string.IsNullOrEmpty(token))
{
context.Token = token;
}
return Task.FromResult<object>(null);
}
public Task ValidateIdentity(OAuthValidateIdentityContext context)
{
context.Validated();
return Task.FromResult<object>(null);
}
}
}
And the AccessTokenProvider
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure;
using Newtonsoft.Json.Linq;
using System;
//using Newtonsoft.Json.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace SomeOAuth
{
public sealed class SomeTokenProvider : AuthenticationTokenProvider
{
public override async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
using (var client = new HttpClient())
{
try
{
var request = new HttpRequestMessage(HttpMethod.Post, "https://someserver/API/Auth/Authenticate");
var s = new StringContent("{\"oauthtoken\":\"" + context.Token + "\"}", Encoding.UTF8, "application/json");
// var ts = s.ToString();
request.Content = new StringContent("{\"oauthtoken\":\"" + context.Token + "\"}", Encoding.UTF8, "application/json");
System.Diagnostics.Debug.WriteLine("Request:");
System.Diagnostics.Debug.WriteLine(request.ToString());
if (request.Content != null)
{
System.Diagnostics.Debug.WriteLine(await request.Content.ReadAsStringAsync());
}
System.Diagnostics.Debug.WriteLine("");
var response = await client.SendAsync(request);
if (response.StatusCode != HttpStatusCode.OK)
{
return;
}
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var userId = payload.Value<string>("username");
//need to get the useid of the user as well as the name and role
var identity = new ClaimsIdentity("Some");
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "someuser", null, "Some"));
/*
identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName + " " + user.LastName));
identity.AddClaim(new Claim(ClaimTypes.Email, user.ContactInfo.Email));
identity.AddClaim(new Claim(ClaimTypes.Sid, user.Guid.ToString()));
*/
identity.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "Some"));
context.SetTicket(new AuthenticationTicket(identity, new AuthenticationProperties()));
}
catch (Exception e)
{
Console.WriteLine("asdf e = " + e.Message);
}
}
}
}
}
You're registering the middleware in the wrong order. The owin middleware model works through the auth middleware placing an instruction (AuthenticationResponseGrant) in the owin dictionary before returning to the previous middleware. If that previous middleware is the external cookie middleware it will issue a cookie. There's more detail in my blog post. So switch those two lines:
// Use a cookie to temp store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseSomeAuthentication(new SomeAuthenticationOptions("testuser", "9"));
There's also another issue. The AuthenticationType of the identity must mach the one of the cookie middleware. The UseExternalSignInCookie method internally calls app.SetDefaultSignInAsAuthenticationType so when you create the new ClaimsIdentity you shouldn't use Some as authentication type but rather convey the result of app.GetDefaultSignInAsAuthenticationType() through the SignInAsAuthenticationType on the options class. The call to app.GetDefaultSignInAsAuthenticationType() is typically done in the middleware constructor.