Configuring ASP.Net core 2.1 using JWT bearer tokens
See original GitHub issueHello all,
I’m having a lot of trouble trying to configure OpenIddict to use JWT tokens for authorization. I’ve spent a lot of time searching, read the docs, and have reviewed this post: #485 with no luck solving the issue.
I have no issues generating tokens, but when I go to use them on my [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
attributed controllers I still get a 401 Unauthorized.
My Startup.cs:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.Converters.Add(new StringEnumConverter());
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDbContext<AuthenticationDbContext>(options =>
{
// Configure the context to use Microsoft SQL Server.
options.UseSqlServer(Configuration["ConnectionStrings:AuthenticationConnection"]);
options.UseOpenIddict();
});
// Register the Identity services.
services
.AddIdentity<ApplicationUser, ApplicationRole>(options => {
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<AuthenticationDbContext>()
.AddSignInManager<ApplicationSignInManager<ApplicationUser>>()
.AddDefaultTokenProviders();
// register custom signin manager with DI
services.AddScoped<SignInManager<ApplicationUser>, ApplicationSignInManager<ApplicationUser>>();
services.Configure<IdentityOptions>(options => {
options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
});
services.AddOpenIddict(options => {
// Register the Entity Framework stores.
options.AddEntityFrameworkCoreStores<AuthenticationDbContext>();
options.AddMvcBinders();
options
.EnableAuthorizationEndpoint("/connect/authorize")
.EnableLogoutEndpoint("/connect/logout")
.EnableTokenEndpoint("/connect/token")
.EnableUserinfoEndpoint("/api/userinfo");
options.SetAccessTokenLifetime(TimeSpan.FromMinutes(60));
options
.AllowAuthorizationCodeFlow()
.AllowPasswordFlow()
.AllowRefreshTokenFlow()
.AllowImplicitFlow();
// Mark the "email", "profile" and "roles" scopes as supported scopes.
options.RegisterScopes(OpenIdConnectConstants.Scopes.Email,
OpenIdConnectConstants.Scopes.Profile,
OpenIddictConstants.Scopes.Roles);
// Make the "client_id" parameter mandatory when sending a token request.
//options.RequireClientIdentification();
options.EnableRequestCaching();
options.EnableScopeValidation();
// not for production, use x509 certificate and .AddSigningCertificate()
options.AddEphemeralSigningKey();
// use jwt
options.UseJsonWebTokens();
});
services.AddCors();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.Authority = "https://localhost:44357/";
options.Audience = "resource_server";
options.RequireHttpsMetadata = false;
options.IncludeErrorDetails = true;
options.TokenValidationParameters = new TokenValidationParameters() {
NameClaimType = OpenIdConnectConstants.Claims.Subject,
RoleClaimType = OpenIdConnectConstants.Claims.Role
};
});
// return LightInject container provider
return Container.CreateServiceProvider(services);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseAuthentication();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseHsts();
app.UseCors(c =>
c.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.AllowCredentials()
);
app.UseHttpsRedirection();
app.UseMvc();
}
My test controller:
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<IActionResult> IndexAsync()
{
UserResponse userResponse = null;
var customer = await _customerService.GetAsync(new Customer() { UserGlobalId = new Guid("A2F75613-7B8B-4C75-AAE8-18548F1DA9AF") });
if (customer != null)
userResponse = _mapper.Map<Customer, UserResponse>(customer, userResponse);
return new ApiOkResponse<UserResponse>(userResponse);
}
And the api request/responses:
Token request:
POST https://localhost:44357/connect/token
{
"username": "test@email.com",
"password": "my_password",
"grant_type": "password"
}
response:
{
"resource": "resource_server",
"token_type": "Bearer",
"access_token": "{ACCESS_TOKEN_VALUE}",
"expires_in": 3600
}
Controller request:
GET https://localhost:44357/api/test
Headers:
Bearer: {ACCESS_TOKEN_VALUE}
Content-Type: application/json
response:
401 Unauthorized
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (3 by maintainers)
Top Results From Across the Web
JWT Authentication In ASP.NET Core
To do this, we need to register a JWT authentication schema by using "AddAuthentication" method and specifying JwtBearerDefaults.
Read more >ASP.NET Core 2.1 - JWT Authentication Tutorial with Example ...
In this tutorial, I demonstrate that how we can implement asp.net web API security using asp.net core 2.1 and JWT(JSON Web Token ),...
Read more >JWT Validation and Authorization in ASP.NET Core
The good news is that authenticating with JWT tokens in ASP.NET Core is straightforward. Middleware exists in the Microsoft.AspNetCore.
Read more >ASP.NET Core Web API v2.1: Authorization
NET Core Web API 2.1 application using the standard JWT middleware. ... Configure the JWT Bearer tokens as the default authentication and challenge...
Read more >JWT token authentication in ASP.NET Core 2.1 ... - YouTube
In this tutorial, I demonstrate how to secure an ASP. NET Core 2.1 Web API web app using JWT ( JSON Web Tokens...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Quick response! I just found the root cause, it was not the aspnet configuration at all, it was in how I was passing the bearer token. I probably misread it somewhere in all my document hunting. Hopefully this helps others, drove me nuts for about 4 hours!
I was doing:
when I should have been doing:
(note the token must be prepended with the word Bearer+[space]). Was testing using Postman.
It’s not an error but an information (as indicated by the log level). If you have an issue, it’s not caused by that. Please open a new thread and post your entire logs.
If you use the latest RC3 bits, don’t miss https://github.com/openiddict/openiddict-core/issues/621