question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Configuring ASP.Net core 2.1 using JWT bearer tokens

See original GitHub issue

Hello 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:closed
  • Created 5 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
replaysMikecommented, Mar 22, 2018

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:

GET https://localhost:44357/api/test
Headers:
  Bearer: {ACCESS_TOKEN_VALUE}
  Content-Type: application/json

when I should have been doing:

GET https://localhost:44357/api/test
Headers:
  Authorization: Bearer {ACCESS_TOKEN_VALUE}
  Content-Type: application/json

(note the token must be prepended with the word Bearer+[space]). Was testing using Postman.

1reaction
kevinchaletcommented, Jun 14, 2018

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

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found