Securing a Web API using multiple token servers

This article shows how a single secure Web API could be used together with multiple secure token servers. The API uses JWT Bearer token authentication, but because the access token come from different token servers, the tokens validation need to be changed.

Code: https://github.com/damienbod/ApiJwtWithTwoSts

Using multiple Authorities with shared certitficate

The first way this can be supported, is that the Authority option is removed from the AddJwtBearer code configuration. When this is removed, the JWT Bearer has no way of validating the Issuer signing. The same certificate which signed the access token, needs to be used in the API as well as the token server. This is easy if you have control of all the applications and can read the certificate from a shared resource like Azure Key Vault. Multiple Issuers can then be supported by configuring the TokenValidationParameters where the signing key is also coded.

public void ConfigureServices(IServiceCollection services)
{
	var x509Certificate2 = GetCertificate(_environment);

	services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
	   .AddJwtBearer(options =>
		{
			options.Audience = "ProtectedApiResource";
			options.TokenValidationParameters = new TokenValidationParameters
			{
				ValidateIssuer = true,
				ValidIssuers = new List<string> { "https://localhost:44318", "https://localhost:44367" },
				ValidateIssuerSigningKey = true,
				IssuerSigningKey = new X509SecurityKey(x509Certificate2),
				IssuerSigningKeyResolver =
				(string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters)
				  => new List<X509SecurityKey> { new X509SecurityKey(x509Certificate2) }
			};
		});

	services.AddAuthorization(options =>
		options.AddPolicy("protectedScope", policy =>
		{
			policy.RequireClaim("scope", "scope_used_for_api_in_protected_zone");
		})
	);

	services.AddControllers();
}

Using multiple Schemes

A different solution would be to use multiple Authentication schemes, a different one for each token service. The Schemes are then added to the default authorization policy. The example shown underneath requires a scope claim scope_used_for_api_in_protected_zone.

public void ConfigureServices(IServiceCollection services)
{
	var x509Certificate2 = GetCertificate(_environment);

	services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
		.AddJwtBearer("JWT", options =>
		{
			options.Audience = "ProtectedApiResourceOne";
			options.Authority = "https://localhost:44318";
		})
		.AddJwtBearer("Custom", options =>
		{
			options.Audience = "ProtectedApiResourceTwo";
			options.Authority = "https://localhost:44367";
		});

	services.AddAuthorization(options =>
	{
		options.DefaultPolicy = new AuthorizationPolicyBuilder()
			.RequireAuthenticatedUser()
			.AddAuthenticationSchemes("JWT", "Custom")
			.Build();

		options.AddPolicy("protectedScope", policy =>
		{
			// scope is required in token from both servers
			policy.RequireClaim("scope", "scope_used_for_api_in_protected_zone");
		});
	  });

	services.AddControllers();
}

Deploy two seperate Web APIs

My favourite solution would be to deploy 2 separate APIs each using a different token service. This would require two separate deployments.

All solutions have advantages, and disadvantages.

Links:

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme

https://docs.microsoft.com/en-us/dotnet/framework/security/json-web-token-handler

One comment

  1. […] Securing a Web API using multiple token servers (Damien Bowden) […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: