It’s a common scenario to add additional API endpoints to the application hosting IdentityServer. These endpoints are typically protected by IdentityServer itself.
For simple scenarios, we give you some helpers. See the advanced section to understand more of the internal plumbing.
You could achieve the same by using either Microsoft’s JwtBearer handler. But this requires more configuration and creates dependencies on external libraries that might lead to conflicts in future updates.
Start by registering your API as an ApiScope, (or resource) e.g.:
var scopes = new List<ApiScope>
{
// local API
new ApiScope(IdentityServerConstants.LocalApi.ScopeName),
};
..and give your clients access to this API, e.g.:
new Client
{
// rest omitted
AllowedScopes = { IdentityServerConstants.LocalApi.ScopeName },
}
The value of IdentityServerConstants.LocalApi.ScopeName is IdentityServerApi.
To enable token validation for local APIs, add the following to your IdentityServer startup:
services.AddLocalApiAuthentication();
To protect an API controller, decorate it with an Authorize attribute using the LocalApi.PolicyName policy:
[Route("localApi")]
[Authorize(LocalApi.PolicyName)]
public class LocalApiController : ControllerBase
{
public IActionResult Get()
{
// omitted
}
}
Authorized clients can then request a token for the IdentityServerApi scope and use it to call the API.
You can also add your endpoints to the discovery document if you want, e.g like this::
services.AddIdentityServer(options =>
{
options.Discovery.CustomEntries.Add("local_api", "~/localapi");
})
Under the covers, the AddLocalApiAuthentication helper does a couple of things:
This covers the most common scenarios. You can customize this behavior in the following ways:
services.AddAuthorization(options =>
{
options.AddPolicy(IdentityServerConstants.LocalApi.PolicyName, policy =>
{
policy.AddAuthenticationSchemes(IdentityServerConstants.LocalApi.AuthenticationScheme);
policy.RequireAuthenticatedUser();
// custom requirements
});
});
You can provide a callback to transform the claims of the incoming token after validation. Either use the helper method, e.g.:
services.AddLocalApiAuthentication(principal =>
{
principal.Identities.First().AddClaim(new Claim("additional_claim", "additional_value"));
return Task.FromResult(principal);
});
…or implement the event on the options if you add the authentication handler manually.