I'm trying to figure out how I can configure SwaggerGen to populate/display the fields/parameters for OpenIddict and client credentials grant.
services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
options.UseOpenIddict();
});
services.AddOpenIddict()
.AddCore(options =>
{
// Configure OpenIddict to use the Entity Framework Core stores and models.
// Note: call ReplaceDefaultEntities() to replace the default entities.
options.UseEntityFrameworkCore().UseDbContext<AppDbContext>();
})
.AddServer(options =>
{
// Enable the token endpoint.
options.SetTokenEndpointUris("/connect/token");
// Enable the client credentials flow.
options.AllowClientCredentialsFlow();
// Register the signing and encryption credentials.
options.AddDevelopmentEncryptionCertificate()
.AddDevelopmentSigningCertificate();
// Register the ASP.NET Core host and configure the ASP.NET Core options.
options.UseAspNetCore()
.EnableTokenEndpointPassthrough();
})
.AddValidation(options =>
{
// Import the configuration from the local OpenIddict server instance.
options.UseLocalServer();
// Register the ASP.NET Core host.
options.UseAspNetCore();
});
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "PCM", Version = "v1" });
options.AddSecurityDefinition("Authentication", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OpenIdConnect,
Description = "Description",
In = ParameterLocation.Header,
Name = "Notsure",
Flows = new OpenApiOAuthFlows
{
ClientCredentials = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri("/connect/token", UriKind.Relative),
TokenUrl = new Uri("/connect/token", UriKind.Relative),
Scopes = new Dictionary<string, string>()
{
}
}
},
OpenIdConnectUrl = new Uri("/connect/authorize", UriKind.Relative)
});
});
It's displaying the Authorize button but when I click it, it opens an empty modal like shown in the below image:
Appreciate anyone who can point me at some docs that would explain what I need to configure in services.AddSwaggerGen()
to get this configured so we can easily test our API through the interactive documentation generated by Swagger.
You need to specify a couple more options when defining an OpenApiSecurityScheme
.
Here's how you can go about setting it up:
TokenUrl
. Client credentials flow works on /token
endpoint, so we have to give it a correct URL. Here I've used IdentityServer's demo serverAuthorization
header with Bearer
scheme.public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(
c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "ApiPlayground", Version = "v1" });
c.AddSecurityDefinition(
"oauth",
new OpenApiSecurityScheme
{
Flows = new OpenApiOAuthFlows
{
ClientCredentials = new OpenApiOAuthFlow
{
Scopes = new Dictionary<string, string>
{
["api"] = "api scope description"
},
TokenUrl = new Uri("https://demo.identityserver.io/connect/token"),
},
},
In = ParameterLocation.Header,
Name = HeaderNames.Authorization,
Type = SecuritySchemeType.OAuth2
}
);
c.AddSecurityRequirement(
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{ Type = ReferenceType.SecurityScheme, Id = "oauth" },
},
new[] { "api" }
}
}
);
}
);
}
Here's how it looks when it's all set up:
Once you authenticate, it gets filled with the token:
Now we can send requests, and Swagger UI includes the token in the headers as we'd expect:
As a finishing touch, we can pre-populate the auth dialog with some default values:
Inside the Startup:Configure
methods where we set up the Swagger UI we can specify client id + secret (which defeats the purpose, but could prove useful in local development)
app.UseSwaggerUI(c => {
c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiPlayground v1");
c.OAuthClientId("m2m");
c.OAuthClientSecret("secret");
});