Define security schemas for Swagger UI to try out authenticated endpoints
You’ve got an API, it’s secured by OAuth using the Client Credentials flow (typically used for server to server communication), and now you want to enable the consumers of your API to try it out in an authenticated way, directly from Swagger. This post is about an API that uses Client Credentials, but it could also be used as a starting point if you want to do the same, but perhaps authenticating end users with the OIDC Authorization code PKCE flow.
This post assumes that:
- You’ve already setup Swagger using Swashbuckle.
- That you have an OAuth client setup in a identity provider somewhere like Okta, Azure AD or a custom Identity Server, and that the client has a allowed scope.
- If you don’t have an OAuth client setup, then you may use Identity server demo with the “m2m” client id, as this is using the Client Credentials flow, and it has a allowed scope (
api
).
This means that you probably have a call to .AddSwaggerGen(...)
in your ConfigureServices
method in Startup.cs
. let’s see what changes we need to do to get our desired end result.
Key points:
- This code uses the configuration from the Identity Server demo.
- The
requiredScope
uses the valueapi
. - The
TokenUrl = new Uri("https://demo.identityserver.io/connect/token")
is the token endpoint in their Discovery document.
- The
- We’re setting a variable
securityDefinitionId
, as we need this in two places.- This is because we need to both add the Security Schema (by calling
AddSecurityDefinition
), and then say that the schema is used by all our endpoints by callingAddSecurityRequirement
. If you want to know more about this, and how to create security schemas that only apply to some endpoints, then have a look at Swagger Authentication.
- This is because we need to both add the Security Schema (by calling
- We’re saying that this is using the Client Credentials flow by setting
Type = SecuritySchemeType.OAuth2
,Scheme = "bearer"
,BearerFormat = "JWT"
, and then defining the ClientCredentials flow. This is the basic configuration for using Client Credentials, but if you’re perhaps using a differentBearerFormat
, then change the configuration accordingly. - You may define multiple scopes (any and all scopes you’ve defined in your identity provider) in the
Scopes =
property. This will enable you to select some, or all of them when authenticating, in order to test endpoints that require different scopes, although we’ve only got a single scope (api
) in this example. - The
{securityScheme, new string[] { requiredScope }}
in.AddSecurityRequirement
, tells Swagger that all our endpoints uses our Security Schema, and that they all require the scopeapi
. - I’m connecting the Security Schema to the Security Requirements a bit differently than in the documentation by moving the
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
from.AddSecurityRequirement()
directly into oursecurityScheme
. - The
new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = securityDefinitionId }
uses oursecurityDefinitionId
for itsId
property, but in the call to.AddSecurityDefinition()
,securityDefinitionId
is used for thename
parameter, this is as expected though.
After we’ve done this, then we will find that the following has been added to our swagger.json
:
And that you’ve got a pretty green button with the text “Authorize” near the top of the page when you access /swagger/index.html, which displays the following when triggered, and allows you to authenticate using Client Credentials. If you’re using Identity server demo to try this out, then you may use the client_id: m2m
and client_secret: secret
, if this doesn’t work, then check on Identity server demo if they’ve changed the credentials for the Client Credentials flow client.
Resources used when finding this solution
- Identity server demo
- Add Security Definitions and Requirements
- How securityDefinition and securityRequirement relates
- API Security in Swagger
Versions used
- .NET core 3.1
- Swashbuckle.AspNetCore 6.1.4
- Swashbuckle.AspNetCore.Annotations 6.1.4