3

I have been banging my head against the wall for a few days now. The solution is probably too simple to state in blogs so I ask the question here.

I am developing a .NET Core Web API which should delegate all authentication and authorization to a Keycloak identity provider server.

I have written the following code in my Startup.cs file:

services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            }).AddJwtBearer(o =>
            {
                o.Authority = "https://idp.abc.xyz/auth/realms/master";
                o.Audience = "products-api";
            });

            services.AddAuthorization(options =>
            {
                options.AddPolicy("Administrator", policy => policy.RequireClaim("user_roles", "product_catalog_admin"));
                options.AddPolicy("User", policy => policy.RequireClaim("user_roles", "product_catalog_user"));


            });

Now I can use Postman to request a token from the IDP and send that token to the Web API. Then the Web API validates that token but does NOT know anything about the IDP other than the URL and only makes a request to a public URL of the IDP to get some configuration.

Question: HOW does the Web API know that the token is valid, not tampered with (created using different key), if it doesn't know anything about the IDP?

1 Answers1

3

AddJwtBearer will use the options you give it to perform in memory validation of tokens. By default this involves the following actions:

  • Validate issuer
  • Validate audience
  • Check that the token's exp claim is not in the past (expired)
  • Verify the access token's digital signature

The 4th check is the most complex and by default this involves downloading token signing public keys from the IDP's JWKS endpoint, then choosing the one in the JWT's kid header. A blog post of mine has some details on how this works.

Of course you should always test the above 4 conditions and ensure that in each case API access is denied with a 401 error response that clients can code against.

Gary Archer
  • 22,534
  • 2
  • 12
  • 24
  • Is this required as well if the audience is the same app/domain issuing the tokens? I passed the `TokenValidationOptions` the `IssuerSigninKey` but upon validation the middleware attempts round trips through some `OpenIdConnectConfigurationRetriever` and other cryptic dependencies to retrieve a document (probably the validation keys you mentioned). Do I have to roll out my custom middleware now or is there some easy way to let the given one just check with the information provided (=the secret)? – Beltway Sep 21 '21 at 13:09
  • The JwtBearer classes should do everything you need without custom code. The behaviour will be to add `.well-known/openid-configuration` to the authority URL to get a discovery document. This doc will provide the JWKS endpoint. The JWKS endpoint will be called to get token signing public keys. When a JWT is received the key to use will be selected from the `kid` field in the JWT header. It can be worth tracing this through manually. – Gary Archer Sep 21 '21 at 13:42
  • The usage of the discovery and metadata URLs is what is bothering me here. I provided the middleware with the secret used for signing, isn't that enough for validation? From what I understand, I now have to set up several additional end-points, generate and provide the public keys and everything that implies, just because the `AddJwtBearer()` expects full OpenId-confirmity under the hood. You mentioned this is the APIs default, but can't one circumvent this behaviour through the options? – Beltway Sep 21 '21 at 14:02
  • 1
    Ah - I see - you don't have the Authorization Server endpoints. Yes - you can definitely bypass the key lookup - I believe [this answer](https://stackoverflow.com/questions/58758198/does-addjwtbearer-do-what-i-think-it-does) shows how. – Gary Archer Sep 21 '21 at 14:18
  • That looks a lot like what I was seeking out for, thanks a ton! – Beltway Sep 21 '21 at 14:23