Protecting APIs¶
IdentityServer issues access tokens in the JWT (JSON Web Token) format by default.
Every relevant platform today has support for validating JWT tokens, a good list of JWT libraries can be found here. Popular libraries are e.g.:
- JWT bearer authentication handler for ASP.NET Core
- JWT bearer authentication middleware for Katana
Protecting an ASP.NET Core-based API is only a matter of adding the JWT bearer authentication handler:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
// base-address of your identityserver
options.Authority = "https://demo.identityserver.io";
// if you are using API resources, you can specify the name here
options.Audience = "resource1";
// IdentityServer emits a typ header by default, recommended extra check
options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
});
}
}
Note
If you are not using the audience claim, you can turn off the audience check via options.TokenValidationParameters.ValidateAudience = false;
. See here for more information on resources, scopes, audiences and authorization.
Validating reference tokens¶
If you are using reference tokens, you need an authentication handler that implements OAuth 2.0 token introspection, e.g. this one:
services.AddAuthentication("token")
.AddOAuth2Introspection("token", options =>
{
options.Authority = Constants.Authority;
// this maps to the API resource name and secret
options.ClientId = "resource1";
options.ClientSecret = "secret";
});
Supporting both JWTs and reference tokens¶
You can setup ASP.NET Core to dispatch to the right handler based on the incoming token, see this blog post for more information. In this case you setup one default handler, and some forwarding logic, e.g.:
services.AddAuthentication("token")
// JWT tokens
.AddJwtBearer("token", options =>
{
options.Authority = Constants.Authority;
options.Audience = "resource1";
options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
// if token does not contain a dot, it is a reference token
options.ForwardDefaultSelector = Selector.ForwardReferenceToken("introspection");
})
// reference tokens
.AddOAuth2Introspection("introspection", options =>
{
options.Authority = Constants.Authority;
options.ClientId = "resource1";
options.ClientSecret = "secret";
});