Search code examples
asp.net-coreswagger-uioktaswashbuckle.aspnetcore

OpenID Connect from Swagger UI with PKCE and Okta in .Net Core


After stepping around controller authorization in the debugger for the past 4 weeks, I finally decided to tackle OpenID Connect authentication in my Swashbuckle-supported .NetCore 5 API. I wish I hadn't, because I spent almost a day so far without a working solution.

Here is a brief recap.

  • Support for OpenID Connect in Swagger-UI is very recent. The only place where I found this information was in Helen's comment to this question. Swagger Ui 3.38.0 is only available in Swashbuckle 6.0.7.
  • Once upgraded to the latest Swashbuckle, I started to see a bunch of "discovered" authorization options in Swagger UI. Alas, PKCE does not appear to be in use, based on the error, even though I explicitly set it in Startup.cs:

.UseSwaggerUI(c => c.OAuthUsePkce());

Also, the ClientSecret there does not make sense, because PKCE is supposed to replace this (and I actually don't have a client secret). My question, does anybody have OpenID Connect with PKCE and Okta working in Swagger UI?

enter image description here

Auth ErrorError, error: invalid_client, description: Browser requests to the token endpoint must use Proof Key for Code Exchange.

Okta application settings


Solution

  • I've recently sitched from an implicit flow to code+pkce flow. I ran into the same issue. The key was to configure the token endopoint url. Swagger UI will still show you the client credentials input box, but you can leave this empty when authorizing.

    var securityDefinition = new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.OAuth2,
        Scheme = "Bearer",
        In = ParameterLocation.Header,
        Name = "Authorization",
        Flows = new OpenApiOAuthFlows
        {
            AuthorizationCode = new OpenApiOAuthFlow
            {
                AuthorizationUrl = new Uri(azureAdOptions.AuthorizeEndpoint),
                TokenUrl = new Uri(azureAdOptions.TokenEndpoint),
                Scopes = azureAdOptions.Applications["Api"].Scopes.ToDictionary(e => e.Value, e => e.Key)
            }
        }
    };
    
    c.AddSecurityDefinition(
        "oauth2",
        securityDefinition);
    
    

    I obviously still have to enable pkce support on the SwaggerUiOptions

    internal static void ConfigureUi(SwaggerUIOptions c, IConfiguration configuration, string apiName, string environmentName)
    {
        c.OAuthUsePkce();
    }
    
    

    I use Azure AD, here are the values I've used:

    AuthorizationUrl: https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize
    TokenUrl: https://login.microsoftonline.com/organizations/oauth2/v2.0/token
    Scopes: custom-value
    

    The commit below contains all the details of how it's implemented. It also contains a test sample. Add support to PKCE for SwaggerUI & update OAuth2Integration sample