Search code examples
c#.netjwtasp.net-core-mvcopeniddict

OpenIddict MVC core 2.0 and JWT on resource server API


I have been setting up an OpenIdDict authserver for use with our existing MVC core 2.0 web application. I am using code flow and made a test MVC webapp resource server before implementing OpenIdConnect part on our production application(s).

Everything seems to be working as intended and I can log in and access my resources.

I need to get API bearer authentication working under new auth architecture for my rest clients. API is placed on the same resource server.

I have set up my OpenIddict for JWT using:

options.AllowPasswordFlow();
options.UseJsonWebTokens();
options.AddSigningKey(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("TokenAuthentication:SecretKey").Value)));

...added JwtBearer:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();

services.AddAuthentication()
    .AddJwtBearer(options =>
    {
        options.Authority = "http://localhost:17004/";
        options.Audience = "MyAudience";
        options.RequireHttpsMetadata = false;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = OpenIdConnectConstants.Claims.Subject,
            RoleClaimType = OpenIdConnectConstants.Claims.Role,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("TokenAuthentication:SecretKey").Value))
        };
    });

...and added code in AuthorizationController.Exchange for handling password flow token requests.

On my resource server Startup.cs I have added AddOpenIdConnect and added signingKey (same key as on my auth server).

options.ResponseType = OpenIdConnectResponseType.Code;
options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;
options.TokenValidationParameters = new TokenValidationParameters()
{
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("TokenAuthentication:SecretKey").Value))
};
options.Authority = "http://localhost:17004/";

After setting this up my resource server can still authenticate and everything is working and I can use a restclient to obtain a jwt token from my auth server but when trying to access my api on resource server it fails because there is no validator for bearer scheme.

If I add call to call AddBearerToken on resource server with the same signingKey in TokenValidationParameters it actually works. The challenge is successful and I have access to my resources.

However I suspect my setup is far from correct since I can see that, when calling my API, validation of my token is happening on resource server so I am left with 2 questions.

  1. Is it possible to have the JwtBearer middleware forward the validation to my auth server? (can openidConnect handle it?)

  2. Is it possible to make my resource server forward/passthru token issue requests too my auth server so my rest api client wont have to deal with 2 servers?


Solution

  • Is it possible to have the JwtBearer middleware forward the validation to my auth server? (can openidConnect handle it?)

    The JWT bearer middleware always performs local validation using the signing key retrieved from OpenIddict's configuration endpoint. You have no way to force it to delegate this task to OpenIddict.

    Is it possible to make my resource server forward/passthru token issue requests too my auth server so my rest api client wont have to deal with 2 servers?

    If you want to delegate the token validation part to your authorization server, then don't use the JWT middleware. Instead, enable introspection in the OpenIddict options, create a new confidential client application registration and use the aspnet-contrib introspection middleware, that will use backchannel HTTP calls to validate the incoming tokens.