Enable Oauth2 client credentials flow in Swashbuckle

mstrand picture mstrand · Nov 17, 2015 · Viewed 13.3k times · Source

Im using IdentityServer3 to secure a Web API with the client credentials grant. For documentation Im using Swashbuckle but can't figure out how to enable Oauth2 in the SwaggerConfig for the client credentials (application) flow. Any help would be appreciated!

Answer

Bill Clyde picture Bill Clyde · May 18, 2016

I was able to get this working. Most of the answer can be found here.

There were a few parts I had to change to get the client_credential grant to work. The first part is in the EnableSwagger and EnableSwaggerUi calls:

config.EnableSwagger(c => 
  {
    c.SingleApiVersion("v1", "sample api");
    c.OAuth2("oauth2")
     .Description("client credentials grant flow")
     .Flow("application")
     .Scopes(scopes => scopes.Add("sampleapi", "try out the sample api"))
     .TokenUrl("http://authuri/token");
    c.OperationFilter<AssignOAuth2SecurityRequirements>();
  }).EnableSwaggerUi(c =>
  {
    c.EnableOAuth2Support("sampleapi", "samplerealm", "Swagger UI");
  });

The important change here is .Flow("application") I also used the .TokenUrl call instead of .AuthorizationUrl This is just dependent on your particular authorization scheme is set up.

I also used a slightly different AssignOAuth2SecurityRequirements class

public class AssignOAuth2SecurityRequirements : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
      var authorized = apiDescription.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>();
      if (!authorized.Any()) return;

      if (operation.security == null)
          operation.security = new List<IDictionary<string, IEnumerable<string>>>();

      var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
      {
          {"oauth2", Enumerable.Empty<string>()}
      };

      operation.security.Add(oAuthRequirements);
    }
}

This should be sufficient to get the authentication switch to show. The other problem for me was that the default authentication dialog is set up so a user just has to select a scope and then click authorize. In my case this didn't work due to the way I have authentication set up. I had to re-write the dialog in the swagger-oauth.js script and inject it into the SwaggerUI.