Swashbuckle.AspNetCore
Swashbuckle.AspNetCore copied to clipboard
Cannot offer both AuthorizationCode PKCE and Client Credentials
Hi everyone, I am using latest Swashbuckle version 6.4.0. For my service which is using IdentityServer as IDP I would like to offer both authorization code with PKCE based authentication as well as client credentials in Swagger. I should say that both auth options work perfectly when I enable them individually. As I am aware to make PKCE working I need to call this here:
app.UseSwaggerUI(
options =>
{
options.OAuthUsePkce();
});
Now I would like to offer client credentials authorization as well, but when the call to OAuthUsePkce is there, the "client_secret" field which is required for client credentials disappears:
How can I bring back the client_secret field without having to disable PKCE?
Thanks in advance.
We have exactly the same problem. 😢 Due to that, we can´t update any more to the latest versions. Please... is it possible to correct this?
Same issue - seems its fixed in this PR - https://github.com/swagger-api/swagger-ui/pull/8146
Better still - it's also fixed for the auth code flow in swagger-api/swagger-ui#8268
Happy to upgrade the related swagger-ui bits once the above changes have been released there. Feel free to ping me with a reminder when that happens
@domaindrivendev It appears to already have been released in 4.15.3.
Thanks everyone involved, I will check the changes soon and will comment here the status.
Hi everyone, the latest stable Swashbuckle.AspNetCore version (6.4.0) relies on swagger-ui-dist 4.14.0 which of course doesn't include the fix from 4.15.3. Is it possible to create a new release with the updated swagger-ui-dist version? Thank you.
We need a new distribution as @sprudel79 mentions.
There was just a recent update a few days back. I have upgraded my local setup and have tested the issue. First of all the latest Swashbuckle.AspNetCore version (6.5.0) uses now swagger-ui-dist 4.15.5. When I run my updated setup locally I can see finally the client_secret field for the clientCredentials flow. Thanks for fixing the issue!
@sprudel79 it appears i have the opposite problem? I am using PKCE auth and do not want the client_secret field shown. after upgrading to 6.5.0 it now shows. is there a way to force it to be hidden?
Hi @aherrick, if you really need to hide the client_secret field you could perhaps try the SwaggerUI options "InjectStylesheet" or "InjectJavascript" to apply the necessary logic.
@sprudel79 Can you share your configuration? Are you using pkce?
Here we go @markwalsh-liverpool, I can share a code snippet (which should show the idea) of the Swagger usage with both PKCE and ClientCredentials:
public virtual void ConfigureServices(IServiceCollection services)
{
...
_ = services.AddSwaggerGen(options =>
{
...
var flows = new OpenApiOAuthFlows();
flows.AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(baseUrlIdentityServer + "/connect/authorize"),
TokenUrl = new Uri(baseUrlIdentityServer + "/connect/token"),
Scopes = new Dictionary<string, string>
{
{ "MyAPI", string.Empty },
{ "openid", string.Empty },
{ "email", string.Empty },
{ "profile",string.Empty}
}
};
flows.ClientCredentials = new OpenApiOAuthFlow
{
TokenUrl = new Uri(baseUrlIdentityServer + "/connect/token"),
Scopes = new Dictionary<string, string>
{
{ "MyAPI", string.Empty }
}
};
options.AddSecurityDefinition("IdentityServer", new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "IdentityServer"
},
In = ParameterLocation.Header,
Name = "Bearer",
Scheme = "oauth2",
Type = SecuritySchemeType.OAuth2,
Flows = flows
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference=new OpenApiReference{Type=ReferenceType.SecurityScheme,Id="IdentityServer"},
Scheme="oauth2",
Name="Bearer",
In=ParameterLocation.Header
},
new List<string>{"openid","email","profile","MyAPI"}
}
});
...
});
...
}
public virtual void Configure(IApplicationBuilder app, IHostApplicationLifetime applicationLifetime)
{
...
_ = app.UseSwagger(o =>
{
});
if (ServiceOptions.Swagger.UseSwaggerUI)
{
var apiVersionDescriptionProvider = app.ApplicationServices.GetRequiredService<IApiVersionDescriptionProvider>();
_ = app.UseSwaggerUI(options =>
{
options.OAuthUsePkce();
foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
{
options.SwaggerEndpoint($"{baseUrlMyAPI}/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
}
});
}
...
}