我正在寻找一种方法来使用 IOperationFilter 确定端点是否需要授权 (.Net Core 3.1)。
如果授权是通过过滤器设置或显式设置为属性,则可以在 OperationFilterContext context.ApiDescription.ActionDescriptor.FilterDescriptors.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter)
中找到它。和context.ApiDescription.CustomAttributes().OfType<AuthorizeAttribute>()
.
但是如果授权设置为
endpoints.MapControllers().RequireAuthorization();
,它应该将 AuthorizationAttribute 添加到所有端点,它既不会出现在过滤器中,也不会出现在属性中。在这种情况下,对于如何捕获身份验证是否应用于端点有什么想法吗?
最佳答案
我今天能够像这样击败它(虚张声势 5.63):
- 创建一个像这样的新类
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Authorization;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace YourNameSpace
{
public class SwaggerGlobalAuthFilter : IOperationFilter
{
public void Apply( OpenApiOperation operation, OperationFilterContext context )
{
context.ApiDescription.TryGetMethodInfo( out MethodInfo methodInfo );
if ( methodInfo == null )
{
return;
}
var hasAllowAnonymousAttribute = false;
if ( methodInfo.MemberType == MemberTypes.Method )
{
// NOTE: Check the controller or the method itself has AllowAnonymousAttribute attribute
hasAllowAnonymousAttribute =
methodInfo.DeclaringType.GetCustomAttributes( true ).OfType<AllowAnonymousAttribute>().Any() ||
methodInfo.GetCustomAttributes( true ).OfType<AllowAnonymousAttribute>().Any();
}
if ( hasAllowAnonymousAttribute )
{
return;
}
// NOTE: This adds the "Padlock" icon to the endpoint in swagger,
// we can also pass through the names of the policies in the List<string>()
// which will indicate which permission you require.
operation.Security = new List<OpenApiSecurityRequirement>
{
new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "oauth2" // note this 'Id' matches the name 'oauth2' defined in the swagger extensions config section below
},
Scheme = "oauth2",
Name = "Bearer",
In = ParameterLocation.Header,
},
new List<string>()
}
}
};
}
}
}
在 swagger 配置扩展中
options.AddSecurityDefinition( "oauth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
Implicit = new OpenApiOAuthFlow
{
//_swaggerSettings is a custom settings object of our own
AuthorizationUrl = new Uri( _swaggerSettings.AuthorizationUrl ),
Scopes = _swaggerSettings.Scopes
}
}
} );
options.OperationFilter<SwaggerGlobalAuthFilter>();
将文档、其他 SO 和内置 SecurityRequirementsOperationFilter
的反编译代码放在一起
据我所知,它正在为所有路由端点定义全局身份验证设置,除了在 Controller 或端点上明确具有 AllowAnonymousAttribute
的端点之外。因为,正如您最初的问题所暗示的那样,在设置路由时使用扩展 RequireAuthorization()
会隐式将该属性放在所有端点上,并且内置的 SecurityRequirementsOperationFilter
会检测 Authorize
属性无法获取它。由于您的路由设置实际上是在每个 Controller /路由上放置 Authorize
,因此似乎设置像这样排除 AllowAnonymous
的默认全局过滤器将与您在中配置的内容一致管道。
我怀疑可能有一种更“内置”的方法可以做到这一点,但我找不到它。
关于asp.net-core - RequireAuthorization 和 Swashbuckle IOperationFilter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62432556/