Home > Back-end >  JWT-based authorization in microservice architecture with dedicated identity service
JWT-based authorization in microservice architecture with dedicated identity service

Time:12-26

I have two services implemented as Web APIs in ASP.NET Core, dockerized and orchestrated (docker-compose and Kubernetes). One service provides authentication and authorization (authNZ, IdentityService), and the other provides resources to authNZ'd users (ResourceService).

Any authenticated user (OIDC-based authentication against Google) has a JWT token, which they can use to add as a bearer token to their API calls to the ResourceService.

Q1: Should ResourceService validate every token calling IdentityService?

Supposing the answer is yes, the authorization middleware of the ResourceService fails with the following error when validating authNZ to an API endpoint.

Authorization failed. These requirements were not met:

DenyAnonymousAuthorizationRequirement: Requires an authenticated user.

Exception occurred while processing message. System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://identity/.well-known/openid-configuration'.

Q2: Do I need to implement the .well-known endpoints in the IdentityService to validate the JWT tokens?

I am aware of the complexities and challenges associated with implementing an Identity service without leveraging dedicated libraries (e.g., IdentityServer4). However, given some licensing issues, I cannot leverage such libraries.

I am sharing some setups I find most relevant, but happy to share other parts of the code if needed.

  • AuthNZ configuration of the ResourceService:
services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.Authority = "https://identity";
    options.Audience = "https://resource";
});
  • AuthNZ configuration of the IdentityService:
services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => 
{
    options.Authority = "https://identity";
    options.Audience = "https://resource";
})
.AddCookie(options =>
{
    options.LoginPath = "/api/v1/authnz/signin";
})
.AddGoogle(GoogleDefaults.AuthenticationScheme, options =>
{
    options.ClientId = "...";
    options.ClientSecret = "...";
    options.CallbackPath = "/authnz/google/callback";
});

CodePudding user response:

Clients and APIs needs to be able to download the configuration document at https://identity/.well-known/openid-configuration and it should be a public document that is not protected in anyway.

When you get this error:

Exception occurred while processing message. System.InvalidOperationException: IDX20803: Unable to obtain configuration from

It is typically because the service can't reach the IdentityProvider. Typically it s a HTTPS or networking issue in your backend.

Every service that provides tokens should preferably expose a configuration document. If you are using IdentityServer, this is built-in.

The alternative is that you provide the public signing key manually to each service.

  • Related