Nswag: AspNet Core 2 Swagger UI: JWT authorization problem

Created on 16 May 2018  路  6Comments  路  Source: RicoSuter/NSwag

I have an ASP.NET Core 2 app and added NSwag to it. I use UseSwaggerUi3WithApiExplorer() and all my controllers/actions show up on the swagger ui page.

Most of my actions require a valid JWT. I've found the following posts, but none of them were working for my case:

Cause I'm still undecided between NSwag and Swashbuckle, I've tried to do the same with Swashbuckle, following this guide:
https://ppolyzos.com/2017/10/30/add-jwt-bearer-authorization-to-swagger-and-asp-net-core/

With Swashbuckle, I get the Authorize button with no problem, I can add my JWT ('Bearer ' + token) and then successfully call the protected actions.

I compared the generated swagger.json files and noticed, that the Swashbuckle version includes this at the end:

"securityDefinitions": {
    "Bearer": {
      "name": "Authorization",
      "in": "header",
      "type": "apiKey",
      "description": "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\""
    }
  },
  "security": Array[1][
    {
      "Bearer": Array[0][

      ]
    }
  ]

whereas the NSwag swagger.json file does not include any securityDefinitions/security entries.

done question

Most helpful comment

I found the problem! For some reason (probably cause I was copy/pasting code from various locations into my sample project), I had in my Configure() the following code:

// NON-WORKING!!!
app.UseSwaggerWithApiExplorer(settings =>
{
    settings.PostProcess = document =>
    {
        document.Info.Version = "v1";
        ...
    };
});

app.UseSwaggerUi3WithApiExplorer(settings =>
{
    settings.DocExpansion = "list";

    settings.GeneratorSettings.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT token"));

    settings.GeneratorSettings.DocumentProcessors.Add(new SecurityDefinitionAppender("JWT token",
        new SwaggerSecurityScheme
        {
            Type        = SwaggerSecuritySchemeType.ApiKey,
            Name        = "Authorization",
            Description = "Copy 'Bearer ' + valid JWT token into field",
            In          = SwaggerSecurityApiKeyLocation.Header,
        }));
});

app.UseMvc();

Only the UseSwaggerWithApiExplorer() got applied then, the call to UseSwaggerUi3WithApiExplorer() was basically ignored (or at least the GeneratorSettings in there, the DocExpansion worked).

So I changed it to the following, and now it's displaying the Authorize button and WORKING:

app.UseSwaggerUi3WithApiExplorer(settings =>
{
    settings.PostProcess = document =>
    {
        document.Info.Version = "v1";
        ...
    };

    settings.DocExpansion = "list";

    settings.GeneratorSettings.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT token"));

    settings.GeneratorSettings.DocumentProcessors.Add(new SecurityDefinitionAppender("JWT token",
        new SwaggerSecurityScheme
        {
            Type        = SwaggerSecuritySchemeType.ApiKey,
            Name        = "Authorization",
            Description = "Copy 'Bearer ' + valid JWT token into field",
            In          = SwaggerSecurityApiKeyLocation.Header,
        }));
});

All 6 comments

This will add the securityDefinitions and scopes:
https://github.com/RSuter/NSwag/wiki/Middlewares#enable-authorization-in-generator-and-swagger-ui

But I think the whole auth stuff is not yet completed for Swagger UI 3...

Also see: https://github.com/RSuter/NSwag/issues/1321#issuecomment-389154006

Hi,

I tried using the app.UseSwaggerUI3 and it seems to be working fine also with OAuth2, but seems that the documentation needs an update. See my example below:

      app.UseSwaggerUi3(typeof(Startup).GetTypeInfo().Assembly, settings =>
            {
                settings.GeneratorSettings.DefaultPropertyNameHandling = PropertyNameHandling.CamelCase;

                settings.OAuth2Client = new OAuth2ClientSettings
                {
                    ClientId = "swagger",
                    ClientSecret = "YourSuperS3cr3tHere"
                };

                settings.GeneratorSettings.DocumentProcessors.Add(new SecurityDefinitionAppender("oauth2", new SwaggerSecurityScheme
                {
                    Type = SwaggerSecuritySchemeType.OAuth2,
                    Description = "Swagger OAuth2",
                    Flow = SwaggerOAuth2Flow.Password,
                    TokenUrl = "http://localhost:64654/connect/token",
                    Scopes = new Dictionary<string, string>
                    {
                        { "openid", "" },
                        { "email", "" },
                        { "profile", "" },
                        { "roles", "" }
                    }
                }));

                settings.GeneratorSettings.OperationProcessors.Add(new OperationSecurityScopeProcessor("oauth2"));
            });

Hope this helps.

Cheers!

I found the problem! For some reason (probably cause I was copy/pasting code from various locations into my sample project), I had in my Configure() the following code:

// NON-WORKING!!!
app.UseSwaggerWithApiExplorer(settings =>
{
    settings.PostProcess = document =>
    {
        document.Info.Version = "v1";
        ...
    };
});

app.UseSwaggerUi3WithApiExplorer(settings =>
{
    settings.DocExpansion = "list";

    settings.GeneratorSettings.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT token"));

    settings.GeneratorSettings.DocumentProcessors.Add(new SecurityDefinitionAppender("JWT token",
        new SwaggerSecurityScheme
        {
            Type        = SwaggerSecuritySchemeType.ApiKey,
            Name        = "Authorization",
            Description = "Copy 'Bearer ' + valid JWT token into field",
            In          = SwaggerSecurityApiKeyLocation.Header,
        }));
});

app.UseMvc();

Only the UseSwaggerWithApiExplorer() got applied then, the call to UseSwaggerUi3WithApiExplorer() was basically ignored (or at least the GeneratorSettings in there, the DocExpansion worked).

So I changed it to the following, and now it's displaying the Authorize button and WORKING:

app.UseSwaggerUi3WithApiExplorer(settings =>
{
    settings.PostProcess = document =>
    {
        document.Info.Version = "v1";
        ...
    };

    settings.DocExpansion = "list";

    settings.GeneratorSettings.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT token"));

    settings.GeneratorSettings.DocumentProcessors.Add(new SecurityDefinitionAppender("JWT token",
        new SwaggerSecurityScheme
        {
            Type        = SwaggerSecuritySchemeType.ApiKey,
            Name        = "Authorization",
            Description = "Copy 'Bearer ' + valid JWT token into field",
            In          = SwaggerSecurityApiKeyLocation.Header,
        }));
});

Yes, UseSwaggerUi3WithApiExplorer also "calls" UseSwaggerWithApiExplorer - so one call will overwrite the other one...

Hi, sorry to revive an old issue!

I'd like to use the same setup:

            Type        = SwaggerSecuritySchemeType.ApiKey,
            Name        = "Authorization",
            Description = "Copy 'Bearer ' + valid JWT token into field",
            In          = SwaggerSecurityApiKeyLocation.Header,

But without having to add bearer. I just wanna add the value of the bearer and be done with it. I'd like NSwag/Swagger/etc. to add "Bearer".

Currently, I have this working with SwashBuckle:

                    Name = "Bearer",
                    BearerFormat = "JWT",
                    Scheme = "bearer",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.Http,

But using this setup doesn't provide what I want with NSwag.. I tried using all other properties but can't get a desired result

Was this page helpful?
0 / 5 - 0 ratings