ASP Net Core 2.2 add locker icon only to methods that require authorization - Swagger UI

后端 未结 2 1655
抹茶落季
抹茶落季 2021-01-12 17:12

Versions:

  • ASP Net Core Web API - 2.2
  • Swashbuckle.AspNetCore - 4.0.1

What I currently have?

I have implemented swagg

2条回答
  •  滥情空心
    2021-01-12 17:17

    For Swashbuckle 5.0.0 and later AddAuthHeaderOperationFilter from @G.Dimov's answer changes to following (with some additional style edits):

    public class AddAuthHeaderOperationFilter : IOperationFilter
    {
        private readonly IHttpContextAccessor httpContextAccessor;
    
        public AddAuthHeaderOperationFilter(IHttpContextAccessor httpContextAccessor)
        {
            this.httpContextAccessor = httpContextAccessor;
        }
    
        public void Apply(Operation operation, OperationFilterContext context)
        {
            var filterDescriptor = context.ApiDescription.ActionDescriptor.FilterDescriptors;
            var isAuthorized = filterDescriptor.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
            var allowAnonymous = filterDescriptor.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);
    
            if (isAuthorized && !allowAnonymous)
            {
                if (operation.Parameters == null)
                    operation.Parameters = new List();
    
                operation.Parameters.Add(new NonBodyParameter
                {
                    Name = "Authorization",
                    In = "header",
                    Description = "JWT access token",
                    Required = true,
                    Type = "string"
                });
    
                operation.Responses.Add("401", new Response { Description = "Unauthorized" });
                operation.Responses.Add("403", new Response { Description = "Forbidden" });
    
                operation.Security = new List>>();
    
                //Add JWT bearer type
                operation.Security.Add(new Dictionary>
                {
                    { "Bearer", new string[] { } }
                });
            }
        }
    }
    

    EDIT

    Swagger UI refuses to send the Authorization header if it is defined as a parameter. So probably better option will be to create a security definition in the SwaggerGen service configuration (usually in Startup.ConfigureServices):

    public void ConfigureServices(IServiceCollection services)
    {
        // Service configuration
        services.AddSwaggerGen(c =>
        {
            // Configure Swagger
            // "Bearer" is the name for this definition. Any other name could be used
            c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "Use bearer token to authorize",
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer",
                    BearerFormat = "JWT"
                });
        }
    }
    

    And then add a security requirement with a reference to a definition to the operation:

    public class AddAuthorizationHeaderOperationHeader : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var actionMetadata = context.ApiDescription.ActionDescriptor.EndpointMetadata;
            var isAuthorized = actionMetadata.Any(metadataItem => metadataItem is AuthorizeAttribute);
            var allowAnonymous = actionMetadata.Any(metadataItem => metadataItem is AllowAnonymousAttribute);
    
            if (!isAuthorized || allowAnonymous)
            {
                return;
            }
            if (operation.Parameters == null)
                operation.Parameters = new List();
    
            operation.Security = new List();
    
            //Add JWT bearer type
            operation.Security.Add(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {                            
                            Reference = new OpenApiReference
                            {                               
                                Type = ReferenceType.SecurityScheme,
                                // Definition name. 
                                // Should exactly match the one given in the service configuration
                                Id = "Bearer"
                            }
                        }, new string[0]
                    }
                }
            );
        }
    }
    

提交回复
热议问题