Custom User and Claims Stores but no claims get set on Controller.User - asp.net-core-identity

// ASP.NET Identity
serviceRegistry.For<IPasswordHasher<User>>().Add<CustomPasswordHasher>();
serviceRegistry.For<CustomDbContext>()
.Use(s => new DesignTimeDbContextFactory().CreateDbContext(Array.Empty<string>()))
.Scoped();
serviceRegistry.AddTransient<IUserStore<User>, CustomUserStore>();
serviceRegistry.AddTransient<IUserClaimStore<User>, CustomUserStore>();
serviceRegistry.AddIdentityCore<User>();
serviceRegistry.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
}).AddIdentityCookies();
I then sign in using the following in my controller action...
var result = await mSignInManager.PasswordSignInAsync(user.Username, model.Password, false, false );
.. and I see UserClaimsPrincipalFactory.GenerateClaimsAsync calling my custom claims store and receiving the expected list of claims.
I have set a break point just beyond the PasswordSignInAsync call but when I look at the User property on the controller there are no claims on there.
Would seem either my config is up the creek, I am missing some code or the order of what I am doing is incorrect or all of the previous! :-(
(All code is work in progress and by no means production ready!)
EDIT:
// I am using Lamar so this is the same as Startup.ConfigureContainer
public static void Configure(ServiceRegistry serviceRegistry, IConfiguration configuration)
{
var clients = ClientHelper.GetClients(configuration);
var tenants = new TenantFactory().CreateTenants(clients);
serviceRegistry.AddHttpContextAccessor();
serviceRegistry.ConfigureOptions<ConfigureMvcOptions>();
serviceRegistry.ConfigureOptions<ConfigureMvcViewOptions>();
serviceRegistry.ConfigureOptions<ConfigureRazorViewOptions>();
serviceRegistry.ConfigureOptions<ConfigureSessionOptions>();
serviceRegistry.ConfigureOptions<ConfigureAntiforgeryOptions>();
serviceRegistry.AddDistributedMemoryCache();
serviceRegistry.AddSession();
serviceRegistry.AddMvc()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
serviceRegistry.AddAntiforgery(opts => opts.FormFieldName = "__RequestVerificationToken");
serviceRegistry.AddRouteAnalyzer();
// ASP.NET Identity
serviceRegistry.For<CustomDbContext>()
.Use(s => new DesignTimeDbContextFactory().CreateDbContext(Array.Empty<string>()))
.Scoped();
serviceRegistry.For<IPasswordHasher<User>>().Add<AtsPasswordHasher>();
serviceRegistry.AddTransient<IUserStore<User>, CustomUserStore>();
serviceRegistry.AddTransient<IUserClaimStore<User>, CustomUserStore>();
serviceRegistry.AddIdentityCore<User>()
.AddSignInManager()
.AddDefaultTokenProviders();
serviceRegistry.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
}).AddIdentityCookies(o => { });
}
Edit 2:
Controller Action - result.Succeeded is true
[AllowAnonymous]
[HttpPost]
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Logon(LogonViewModel model)
{
if (ModelState.IsValid)
{
var user = await mUserManager.FindByNameAsync(model.Username);
var result = await mSignInManager.PasswordSignInAsync(user.Username, model.Password, false, false );
if (result.Succeeded)
{
mLogger.LogInformation(1, "User logged in.");
try
{
var sessionState = CreateSessionState(user.Username, mUserStateManager.ClientIpAddress);
var sessionData = CreateSessionData(sessionState, user);
mSessionWrapper.Session = sessionData;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
return RedirectToAction("SessionCreated",
new
{
returnUrl = string.IsNullOrEmpty(model.ReturnUrl)
? Request.Query["ReturnUrl"].ToString()
: model.ReturnUrl,
username = model.Username,
currentpassword = model.ResetToken
});
//return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
//return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
}
if (result.IsLockedOut)
{
mLogger.LogWarning(2, "User account locked out.");
//return View("Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// Default to returning the original view once more
return View("Logon", model);
}
User Store and Claims Store - FindByNameAsync and GetClaimsAsync work
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Core.Auth.Model;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
namespace Core.Auth.Identity.EFCore
{
public class CustomUserStore : IUserStore<User>, IUserClaimStore<User>, IUserPasswordStore<User>
{
private bool mDisposed;
private CustomUserStore() { }
public CustomUserStore(CustomDbContext context)
{
Context = context ?? throw new ArgumentNullException(nameof(context));
}
public virtual CustomDbContext Context { get; private set; }
private DbSet<User> Users => Context.Set<User>();
#region IUserStore<User> implementation
public void Dispose()
{
mDisposed = true;
}
public async Task<string> GetUserIdAsync(User user, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
var foundUser = await FindUserById(user, cancellationToken);
return foundUser?.UserId.ToString();
}
public async Task<string> GetUserNameAsync(User user, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
var foundUser = await FindUserById(user, cancellationToken);
return foundUser?.Username;
}
public Task SetUserNameAsync(User user, string userName, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<string> GetNormalizedUserNameAsync(User user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task SetNormalizedUserNameAsync(User user, string normalizedName, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityResult> CreateAsync(User user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityResult> UpdateAsync(User user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityResult> DeleteAsync(User user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public async Task<User> FindByIdAsync(string userId, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
return await Users.FirstOrDefaultAsync(x => x.UserId.ToString() == userId, cancellationToken: cancellationToken);
}
public Task<User> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
return Users.FirstOrDefaultAsync(u => u.Username == normalizedUserName, cancellationToken);
}
#endregion
#region IUserClaimStore<User> implementation
public async Task<IList<Claim>> GetClaimsAsync(User user, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
// Data model is a little "odd" so having to this in a mechanical fashion for now
var securityRoleIdsForUser = await Context
.UserToSecurityRoles
.Where(x => x.UserId == user.UserId)
.Select(x => x.SecurityRoleId)
.ToArrayAsync( cancellationToken);
var securityRoles = await Context
.SecurityRoles
.Where(x => securityRoleIdsForUser.Contains(x.SecurityRoleId))
.Select(x => x.SecurityRoleName)
.ToArrayAsync(cancellationToken);
var claims = securityRoles.Select(securityRole => new Claim(ClaimTypes.Role, securityRole)).ToList();
return claims;
}
public Task AddClaimsAsync(User user, IEnumerable<Claim> claims, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task ReplaceClaimAsync(User user, Claim claim, Claim newClaim, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task RemoveClaimsAsync(User user, IEnumerable<Claim> claims, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IList<User>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
#endregion
#region IUserPasswordStore<User> implementation
public Task SetPasswordHashAsync(User user, string passwordHash, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public async Task<string> GetPasswordHashAsync(User user, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
var foundUser = await FindUserById(user, cancellationToken);
return foundUser.Rfc2898PasswordHash;
}
public Task<bool> HasPasswordAsync(User user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
#endregion
/// <summary>
/// Throws if this class has been disposed.
/// </summary>
protected void ThrowIfDisposed()
{
if (mDisposed)
{
throw new ObjectDisposedException(GetType().Name);
}
}
private async Task<User> FindUserById(User user, CancellationToken cancellationToken)
{
var foundUser = await Users.FirstOrDefaultAsync(x => x.UserId == user.UserId, cancellationToken: cancellationToken);
return foundUser;
}
}
}

Related

Can't catch HttpRequestException when using HttpMessageHandler

I'm using HttpMessageHandler to log Http Request and Response. If internet connection is not available I get HttpRequestException, but this Exception is not catched (try catch not working). If I don't use HttpMessageHandler Exception is catched.
Method with try catch :
public JObject Get()
{
string url = "/...";
try
{
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert,
chain, errors) =>
{ return true; };
using (var client = new HttpClient(new LoggingHandler(httpClientHandler)))
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue(CONTENT_TYPE_JSON));
var byteArray = Encoding.ASCII.GetBytes("");
client.DefaultRequestHeaders.Authorization = new
System.Net.Http.Headers.AuthenticationHeaderValue("Basic",
Convert.ToBase64String(byteArray));
HttpResponseMessage response = client.GetAsync(url).Result;
response.EnsureSuccessStatusCode();
var json = response.Content.ReadAsStringAsync().Result;
JObject rss = JObject.Parse(json);
return rss;
}
}
}
catch(HttpRequestException ex)
{
//Catch not working
return null;
}
}
HttpMessageHandler :
public class LoggingHandler : DelegatingHandler
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(LoggingHandler));
public LoggingHandler(HttpMessageHandler innerHandler)
: base(innerHandler)
{
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
HttpResponseMessage response = null;
Loging("Request:");
Loging(request.ToString());
if (request.Content != null)
{
Loging(await request.Content.ReadAsStringAsync());
}
Loging("");
response = await base.SendAsync(request, cancellationToken);
Loging("Response:");
Loging(response.ToString());
if (response.Content != null)
{
Loging(await response.Content.ReadAsStringAsync());
}
Loging("");
return response;
}
private void Loging(string message)
{
Debug.WriteLine(message);
log.Info(message);
}
}
Why is it happining?

Multiple authentication attributes

I`m working on my website using .net web-api as back .
Now I made different authentication attributes on the web site such as users employees and admin .
for my question how can I use multiple authentication attributes on a controller?
public class AuthFilterManager : Attribute, IAuthenticationFilter
{
public bool AllowMultiple => throw new NotImplementedException();
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var auth = context.Request.Headers.Authorization;
string[] UserNameAndPass = (auth.Parameter).Split(':');
string UserName = UserNameAndPass[0];
string Pass = UserNameAndPass[1];
Luxury_wheelsEntities entities = new Luxury_wheelsEntities();
Management manager = entities.Managements.FirstOrDefault(m => m.User_name == UserName);
if (auth != null && auth.Scheme == "LuxuryWheelsLogin")
{
if (LoginSecurity.CheckManagerLogin(UserName, Pass))
{
var Claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier,(manager.ID)),
new Claim(ClaimTypes.Name,(manager.Full_name)),
new Claim(ClaimTypes.Gender,(manager.Sex))
};
var identity = new ClaimsIdentity(Claims, "Token");
context.Principal = new ClaimsPrincipal(new[] { identity });
}
else
{
context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
}
}
return Task.FromResult(0);
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
return Task.FromResult(0);
}
}
seperatly the AuthFilterEmployee and the AuthFilterManager works just fine.
[AuthFilterEmployee ]
[AuthFilterManager]
[Authorize]
public IEnumerable<User> Get()
{
return LuxuryWheelsDB.Users;
}

webapi-use claims with windows authentication

The method has been secured with roles=admin:
[Authorize(Roles = "admin")]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}}
I am successfully to use claims with Webapi project where Individual User Account is selected where the claim admin is injected in
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
// Add custom user claims here
userIdentity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
return userIdentity;
}
}
Now I want to test with Windows authentication option where a IAuthenticationFilter is implemented:
public class CustomAuthenticationFilter : IAuthenticationFilter
{
public bool AllowMultiple { get { return true; } }
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var windowsPrincipal = context.Principal as WindowsPrincipal;
if (windowsPrincipal != null)
{
var name = windowsPrincipal.Identity.Name;
// TODO: fetch claims from db (i guess based on name)
var identity = new ClaimsIdentity(windowsPrincipal.Identity);
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
var claimsPrincipal = new ClaimsPrincipal(identity);
// here is the punchline - we're replacing original windows principal
// with our own claims principal
context.Principal = claimsPrincipal;
}
return Task.FromResult(0);
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
return Task.FromResult(0);
}
}
and added to class webapiconfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Filters.Add(new CustomAuthenticationFilter());
...
}
}
The claim admin is in User.Identity.Claims when debugging webapi project, however it could not be authorized in method /api/values/get.
Any idea?
The default identity RoleClaimType is identity/claims/groupsid which is not role.
By setting RoleClaimType to identity/claims/role in the ClaimsIdentity constructor, we can get it passing [Authorize(Roles = "admin")]
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var windowsPrincipal = context.Principal as WindowsPrincipal;
if (windowsPrincipal != null)
{
var name = windowsPrincipal.Identity.Name;
// TODO: fetch claims from db (i guess based on name)
var identity = new ClaimsIdentity(windowsPrincipal.Identity,
null,
"Negotiate",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
//identity
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
var claimsPrincipal = new ClaimsPrincipal(identity);
// here is the punchline - we're replacing original windows principal
// with our own claims principal
context.Principal = claimsPrincipal;
}
return Task.FromResult(0);
}
Here is the new identity:

Simple Injector inject dependency into custom global authentication filters and OWIN middle ware OAuthAuthorizationServerProvider

I used Simple Injector as our Ioc container; we have two problems.
We want to inject into our custom authentication filter; we read the post of converting attribute to a passive attribute: Convert Attribute into a passive. But we can't convert custom authentication filter attribute into a passive.
public class BearerAuthentication : Attribute, IAuthenticationFilter
{
public async Task AuthenticateAsync(
HttpAuthenticationContext context, CancellationToken cancellationToken)
{
}
public Task ChallengeAsync(
HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
}
}
We want to inject dependency into OWin middleware OAuthAuthorizationServerProvider; we know we can use begin execution context scope, but we want an elegant solution.
using (Ioc.Container.BeginExecutionContextScope())
{
}
Updated
public interface IAuthenticationFilter<TAttribute> where TAttribute : Attribute
{
Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken);
Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken);
}
public class BearerAuthenticationFilter : Attribute, IAuthenticationFilter<BearerAuthenticationFilter>
{
private readonly IAuthenticationBusinessEngine _authenticationBusinessEngine;
private readonly IHttpContextAccessor _httpContextAccessor;
public BearerAuthenticationFilter(IAuthenticationBusinessEngine authenticationBusinessEngine, IHttpContextAccessor httpContextAccessor)
{
_authenticationBusinessEngine = authenticationBusinessEngine;
_httpContextAccessor = httpContextAccessor;
}
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
public class AuthenticationFilterDispatcher : IAuthenticationFilter
{
private readonly Func<Type, IEnumerable> _container;
public AuthenticationFilterDispatcher(Func<Type, IEnumerable> container)
{
_container = container;
}
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var descriptor = context.ActionContext.ActionDescriptor;
var attributes = descriptor.ControllerDescriptor.GetCustomAttributes<Attribute>(true)
.Concat(descriptor.GetCustomAttributes<Attribute>(true));
foreach (var attribute in attributes)
{
var filterType = typeof(IAuthenticationFilter<>).MakeGenericType(attribute.GetType());
var filters = _container.Invoke(filterType);
foreach (dynamic actionFilter in filters)
{
await actionFilter.AuthenticateAsync(context, cancellationToken);
}
}
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public bool AllowMultiple
{
get
{
return true;
}
}
}
The equivalent code for working with IAuthenticationFilter is:
public interface IAuthenticationFilter<TAttribute> where TAttribute : Attribute
{
Task AuthenticateAsync(TAttribute attribute, HttpAuthenticationContext context);
}
public class AuthenticationFilterDispatcher : IAuthenticationFilter
{
private readonly Func<Type, IEnumerable> container;
public AuthenticationFilterDispatcher(Func<Type, IEnumerable> container) {
this.container = container;
}
public async Task AuthenticateAsync(HttpAuthenticationContext context,
CancellationToken token) {
var descriptor = context.ActionContext.ActionDescriptor;
var attributes = descriptor.ControllerDescriptor
.GetCustomAttributes<Attribute>(true)
.Concat(descriptor.GetCustomAttributes<Attribute>(true));
foreach (var attribute in attributes) {
Type filterType = typeof(IAuthenticationFilter<>)
.MakeGenericType(attribute.GetType());
IEnumerable filters = this.container.Invoke(filterType);
foreach (dynamic actionFilter in filters) {
await actionFilter.AuthenticateAsync((dynamic)attribute, context);
}
}
}
public async Task ChallengeAsync(HttpAuthenticationChallengeContext context,
CancellationToken token) { }
public bool AllowMultiple { get { return true; } }
}
Registration is done as follows:
GlobalConfiguration.Configuration.Filters.Add(
new AuthenticationFilterDispatcher(container.GetAllInstances));
// For Simple Injector 2.x:
container.RegisterManyForOpenGeneric(typeof(IAuthenticationFilter<>),
container.RegisterAll,
new[] { typeof(IAuthenticationFilter<>).Assembly });
// For Simple Injector 3.x:
container.RegisterCollection(typeof(IAuthenticationFilter<>),
new[] { typeof(IAuthenticationFilter<>).Assembly });
Now instead of making your attributes active, you can make the attribute passive and implement the required logic inside an IAuthenticationFilter<MyPassiveAttribute> implementation.
Your attribute and new component might look like this:
// NOTE: This attribute does not derive from anything Web API specific,
// just from Attribute
public class RequiresBearerAuthenticationAttribute : Attribute
{
// put here properties if required
}
public class BearerAuthenticationFilter
: IAuthenticationFilter<RequiresBearerAuthenticationAttribute>
{
private readonly IAuthenticationBusinessEngine _authenticationBusinessEngine;
private readonly IHttpContextAccessor _httpContextAccessor;
public BearerAuthenticationFilter(
IAuthenticationBusinessEngine authenticationBusinessEngine,
IHttpContextAccessor httpContextAccessor)
{
_authenticationBusinessEngine = authenticationBusinessEngine;
_httpContextAccessor = httpContextAccessor;
}
public async Task AuthenticateAsync(RequiresBearerAuthenticationAttribute attribute,
HttpAuthenticationContext context)
{
// TODO: Behavior here
}
}

SignalR Authorize attribute not called

I have a hub that does not convert the token located at Authorization:Bearer eyjsdalfsadlfjffdafs... in the request header to an identity. The rest of the API works fine with standard http verbs however for some reason SignalR is not authorizing the token into a user.
public class ChatHub : Hub
{
[Authorize]
public override Task OnConnected()
{
// error context.user.identity.name =""
var userId = int.Parse(Context.User.Identity.Name);
return base.OnConnected();
}
....
}
Startup.cs
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
JwtHandler - this part of the filter is not called when the client connects to the hub even though onConnect() is attributed with [Authorize]
public class JwtHandler : DelegatingHandler
{
private const string ISSUER = "Issuer";
private const string AUDIENCE = "Audience";
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
byte[] key = Convert.FromBase64String("SecretKey");
try
{
var headers = request.Headers;
if(headers.Authorization != null)
{
if(headers.Authorization.Scheme.Equals("Bearer"))
{
string jwt = request.Headers.Authorization.Parameter;
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
TokenValidationParameters parms = new TokenValidationParameters()
{
ValidAudience = AUDIENCE,
ValidIssuers = new List<string>(){ISSUER},
IssuerSigningToken = new BinarySecretSecurityToken(key),
};
SecurityToken validated = new JwtSecurityToken(jwt);
var principal = tokenHandler.ValidateToken(jwt, parms,out validated);
Thread.CurrentPrincipal = principal;
if(HttpContext.Current !=null)
{
HttpContext.Current.User = principal;
}
}
}
var response = await base.SendAsync(request, cancellationToken);
if(response.StatusCode == HttpStatusCode.Unauthorized)
{
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Bearer", "error=\"invalid_token\""));
return response;
}
return response;
}catch (Exception)
{
var response = request.CreateResponse(HttpStatusCode.Unauthorized);
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Bearer", "error=\"invalid_token\""));
return response;
}
}
}
Try validating the jwt token in the OWIN middleware. In your Startup.cs add:
public void Configuration(IAppBuilder app)
{
app.UseJwtBearerAuthentication(
new Microsoft.Owin.Security.Jwt.JwtBearerAuthenticationOptions() {
AllowedAudiences = new string[] { ALLOWEDAUDIENCE },
IssuerSecurityTokenProviders = new[] {
new SymmetricKeyIssuerSecurityTokenProvider(ISSUER, System.Convert.FromBase64String(cKey))
}
});
app.MapSignalR();
}

Resources