Home > Software engineering >  Using Swashbuckle Swagger to keep Authorize when selecting a different definition
Using Swashbuckle Swagger to keep Authorize when selecting a different definition

Time:11-17

I've set up a C# project that uses swashbuckler swagger. I've been able to create an Authorize button on one of my definitions successfully. But when adding a new definition, I can't Authorize that new definition, and all my endpoints return a 401 unauthorized. I can only Authorize on the default definition.

In startup.cs I have:

 public void ConfigureServices(IServiceCollection services)
 {
      ......

     services.AddAuthentication("Basic")
            .AddScheme<BasicAuthenticationOptions, CustomAuthenticationHandler>("Basic", null);

        services.AddHttpContextAccessor();
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "App-Test", Version = "v1" });
            c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = $"desc",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey,
                Scheme = "bearer" 
            });

            c.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        }
                    }, new List<string>()
                }
            });
        });

      ......
 }

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger();
            app.UseSwaggerUI(c => {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "App-Test v1"); // able to auth
                c.SwaggerEndpoint("/$openapi", "OData raw OpenAPI"); // no auth
            });
        }

   // accesses middleware developed from a demo here: 
   // https://github.com/OData/AspNetCoreOData/tree/main/sample/ODataRoutingSample/OpenApi
   app.UseOdataOpenApi()
   ......
}

In the Configure() method, I created two definitions. One titled "App-Test v1", and another one titled "OData raw OpenApi."

When I run my app and navigate to http://localhost:5000/swagger, I'm able to view the definition for "App-Test v1" and able to Authorize. Therefore, all my endpoints on this definition can be executed.

However, when I switch to a different definition, "Odata raw OpenApi", the Authorize button is no longer there. When I try to execute one of my endpoints, I get a 401 unauthorized.

Is there a way to bring over the bearer token from the first definition to the second? Or create a new Authorize button on the second definition? I've read the documents and I couldn't figure out how to do this.

CodePudding user response:

Thanks to CodingMytra in the comment pointing me in the right direction, I had to update this document:

https://github.com/OData/AspNetCoreOData/blob/main/sample/ODataRoutingSample/OpenApi/OpenApiDocumentExtensions.cs

I added the following code at the bottom of CreateDocument()

 ......

        OpenApiConvertSettings settings = new OpenApiConvertSettings
        {
            PathProvider = provider,
            ServiceRoot = BuildAbsolute(context, prefixName)
        };

        var securiteSchemes = new Dictionary<string, OpenApiSecurityScheme>();
        securiteSchemes.Add("Bearer"
            , new OpenApiSecurityScheme
            {
                Description = $"desc",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey,
                Scheme = "bearer"
            });

        var securiteRequirements = new List<OpenApiSecurityRequirement>();
        securiteRequirements.Add(
            new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        }
                    }, new List<string>()
                }
            });

        var openDoc = model.ConvertToOpenApi(settings);
        openDoc.Components.SecuritySchemes = securiteSchemes;
        openDoc.SecurityRequirements = securiteRequirements;

        return openDoc;
}

CodePudding user response:

You can use AllowAnonymous attribute with those methods in which you want to skip the authorization.

[AllowAnonymous]
public ActionResult SomeMethod()
{
}
  • Related