I'm using Asp.net core rc2 with OpenIdConnectServer. I'm using angular 1.x with augular-oauth2. After a few days, my error has digressed to
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:54275/api/Account/Username Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: Successfully validated the token. Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Bearer. Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: AuthenticationScheme: Bearer was successfully authenticated. Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed for user: . Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Warning: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes (Bearer). Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: AuthenticationScheme: Bearer was forbidden.
My ConfigureServices consists of
services.AddAuthorization(options => { options.AddPolicy("UsersOnly", policy => { policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme); policy.RequireClaim("role"); }); });
My configure has
app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), branch => { branch.UseJwtBearerAuthentication(new JwtBearerOptions { AutomaticAuthenticate = true, AutomaticChallenge = true, RequireHttpsMetadata = false, Audience = "http://localhost:54275/", Authority = "http://localhost:54275/", TokenValidationParameters = new TokenValidationParameters { ValidAudience = "client1", //ValidAudiences = new List<string> { "", "empty", "null"} } }); }); app.UseOpenIdConnectServer(options => { options.AuthenticationScheme = OpenIdConnectServerDefaults.AuthenticationScheme; options.Provider = new SimpleAuthorizationServerProvider(); options.AccessTokenHandler = new JwtSecurityTokenHandler(); options.ApplicationCanDisplayErrors = true; options.AllowInsecureHttp = true; options.TokenEndpointPath = new PathString("/oauth2/token"); options.LogoutEndpointPath = new PathString("/oauth2/logout"); options.RevocationEndpointPath = new PathString("/oauth2/revoke"); options.UseJwtTokens(); //options.AccessTokenLifetime = TimeSpan.FromHours(1); });
My authorize attribute is defined on the Controller as
[Authorize(Policy = "UsersOnly", ActiveAuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme), Route("api/Account")]
I store the token as a cookie and attach it to requests using an http interceptor in angular.
I generate the token with
public override async Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context) { // validate user credentials (demo mode) // should be stored securely (salted, hashed, iterated) using (var con = new SqlConnection(ConnectionManager.GetDefaultConnectionString())) { if (!Hashing.ValidatePassword(context.Password, await con.ExecuteScalarAsync<string>("SELECT PassHash FROM dbo.Users WHERE Username = @UserName", new { context.UserName }))) { context.Reject( error: "bad_userpass", description: "UserName/Password combination was invalid." ); return; } // create identity var id = new ClaimsIdentity(context.Options.AuthenticationScheme); id.AddClaim(new Claim("sub", context.UserName)); id.AddClaim(new Claim("role", "user")); // create metadata to pass on to refresh token provider var props = new AuthenticationProperties(new Dictionary<string, string> { {"as:client_id", context.ClientId} }); var ticket = new AuthenticationTicket(new ClaimsPrincipal(id), props, context.Options.AuthenticationScheme); ticket.SetAudiences("client1"); //ticket.SetScopes(OpenIdConnectConstants.Scopes.OpenId, OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile, "api-resource-controller"); context.Validate(ticket); } }
I've spent the last three days on this problem and I realize that at this point I'm probably missing something obvious due to lack of sleep. Any help would be appreciated.