Search code examples
c#asp.net-coreoauth-2.0identityserver4asp.net-authorization

How to customize token validation on IdentityServer?


OAuth flow

As described in the above picture each API Call to the Resource provider (RP) with JWT access token RP ensures token reliability by asking from the IDP server, now I need to add my customization to check token reliability on the IDP side.

I Implement these interfaces in IDP :

1- ICustomTokenRequestValidator

2- ICustomAuthorizeRequestValidator

3- IJwtRequestValidator

and register them by these methods:

1- AddCustomTokenRequestValidator()

2- AddCustomAuthorizeRequestValidator()

3- services.RemoveAll();

services.AddTransient<IJwtRequestValidator, XaniisAuthorizeRequestValidator>();

and it is my expectation that when I call an authorized API endpoint on (RP) my breakpoint on one of these implementations Hits. but there is no hit on my breakpoints. is there any other interface or service responsible for JWT token reliability check?

Update:

I checked my network using Wireshark. and I noticed that there is no request to the IDP server when there is a request on the RP server. Is there any option to enable/disable Idp JWT token validation request (request #4)?

Update 2:

I found that there is a /connect/introspect endpoints on the IDP that can check the validity of JWT. now the question is this: How can I Enforce my RP to check JWT token validity by calling this API? and is it a good approach to check JWT token? This is the link to the documentation of introspecting endpoint


Solution

  • You can disable the request to the IDP from the API (#4) entirely by providing the IDP public key to the API directly, like hard-coded.

    Otherwise, the JwtBearer handler will by default query the IDP every 24 hours to get new keys/config, like how this picture below show:

    enter image description here

    If you use the JwtBearer library, I doubt you can have it to call the introspection endpoint for every request. However, there are a set of event handlers in JwtBearer that you can use to call the introspection enpoint manually on every request:

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(opt =>
    {
        opt.Audience = "payment";      
        opt.Authority = "https://localhost:6001";
    
        opt.Events.OnMessageReceived = context =>
        {
            // When Authenticate is called
            return Task.CompletedTask;
        };
        opt.Events.OnAuthenticationFailed = context =>
        {
            // When exceptions are thrown during request processing (invalid token...)
            return Task.CompletedTask;
        };
        opt.Events.OnChallenge = context =>
        {
            // Invoked before a challenge is sent back to the caller.
            return Task.CompletedTask;
        };
        opt.Events.OnForbidden = context =>
        {
            // Invoked if Authorization fails and results in a Forbidden response
            return Task.CompletedTask;
        };
        opt.Events.OnTokenValidated = context =>
        {
            // Token has passed validation and a ClaimsIdentity has been generated.
            return Task.CompletedTask;
        };
    });