如何查看哪个 AuthorizeAttribute 失败 ASP.NET Core
How can I see which AuthorizeAttribute Failed ASP.NET Core
我正在尝试找出是否有一种简单的方法让 ASP.NET 核心记录哪个 [Authorize]
属性失败。我混合使用了“角色”和“策略”授权属性,但只要有一个失败,日志就会显示:
显然这是正确的行为,它不会让拥有不正确权限的人进入,但是如果您有多个属性,那么必须去找出哪个失败是一件很痛苦的事情。如果日志只显示 Authorization failed for Policy X
那么就很容易找到失败的原因。
有谁知道目前是否可以通过一些我不知道的选项来实现这一点?
编辑: 例如:如果我有 [Authorize(Policy = "Policy 1")]
和 [Authorize(Policy = "Policy 2")]
并且只有“策略 2”失败。我希望看到一些信息告诉我是“策略 2”失败了。
编辑: 对于仍然遇到此问题的任何人,此问题现在已由 Microsoft 实施并且是 .NET 5.0 的一部分,请参阅问题 https://github.com/aspnet/AspNetCore/issues/7789
你可以在里面处理和记录这个 Middlewares
public class AuthHandlerMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ErrorHandlingMiddleware> _logger;
public AuthHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context, IHostingEnvironment env /* other scoped dependencies */)
{
await _next(context);
if (context.Response.StatusCode == 401)
_logger.LogInformation($"'{context.User.Identity.Name}' is unauthorized");
}
}
在您的启动配置中,
public void Configure(IApplicationBuilder app, ... )
{
....
app.UseMiddleware<AuthHandlerMiddleware>();
}
对于 Roles
和 Policy
,它们被转换为 RolesAuthorizationRequirement
等要求或 MinimumAgeRequirement
等您的自定义要求。
对于 Authorization failed.
,这是由 DefaultAuthorizationService
在 AuthorizeAsync
中记录的,您可能无法获得像 Policy 1
和 Policy 2
这样的确切名称。您可以获得 Policy
的要求。
尝试检查以下解决方法是否符合您的要求。
实施自定义 DefaultAuthorizationService
public class CustomAuthorizationService : DefaultAuthorizationService, IAuthorizationService
{
private readonly AuthorizationOptions _options;
private readonly IAuthorizationHandlerContextFactory _contextFactory;
private readonly IAuthorizationHandlerProvider _handlers;
private readonly IAuthorizationEvaluator _evaluator;
private readonly IAuthorizationPolicyProvider _policyProvider;
private readonly ILogger _logger;
public CustomAuthorizationService(IAuthorizationPolicyProvider policyProvider
, IAuthorizationHandlerProvider handlers
, ILogger<DefaultAuthorizationService> logger
, IAuthorizationHandlerContextFactory contextFactory
, IAuthorizationEvaluator evaluator
, IOptions<AuthorizationOptions> options)
: base(policyProvider, handlers, logger, contextFactory, evaluator, options)
{
_options = options.Value;
_handlers = handlers;
_policyProvider = policyProvider;
_logger = logger;
_evaluator = evaluator;
_contextFactory = contextFactory;
}
public new async Task<AuthorizationResult> AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerable<IAuthorizationRequirement> requirements)
{
if (requirements == null)
{
throw new ArgumentNullException(nameof(requirements));
}
var authContext = _contextFactory.CreateContext(requirements, user, resource);
var handlers = await _handlers.GetHandlersAsync(authContext);
foreach (var handler in handlers)
{
await handler.HandleAsync(authContext);
if (!_options.InvokeHandlersAfterFailure && authContext.HasFailed)
{
break;
}
}
var result = _evaluator.Evaluate(authContext);
if (result.Succeeded)
{
_logger.LogInformation($"Authorization is succeeded for { JsonConvert.SerializeObject(requirements) }" );
//_logger.UserAuthorizationSucceeded();
}
else
{
//var r = result.Failure.FailedRequirements.Select(requirement => new { Requirement = requirement.GetType() });
var json = JsonConvert.SerializeObject(result.Failure.FailedRequirements);
_logger.LogInformation($"Authorization is failed for { json }");
//_logger.UserAuthorizationFailed();
}
return result;
}
}
替换内置DefaultAuthorizationService
services.AddAuthorization(config =>
{
config.AddPolicy("T1", policy => policy.AddRequirements(new MinimumAgeRequirement(21)));
});
services.Replace(ServiceDescriptor.Transient<IAuthorizationService, CustomAuthorizationService>());
Microsoft 在 .NET 5.0 中默认实现此功能,请参阅相关 GitHub 问题了解详细信息和 PR 链接。
我正在尝试找出是否有一种简单的方法让 ASP.NET 核心记录哪个 [Authorize]
属性失败。我混合使用了“角色”和“策略”授权属性,但只要有一个失败,日志就会显示:
显然这是正确的行为,它不会让拥有不正确权限的人进入,但是如果您有多个属性,那么必须去找出哪个失败是一件很痛苦的事情。如果日志只显示 Authorization failed for Policy X
那么就很容易找到失败的原因。
有谁知道目前是否可以通过一些我不知道的选项来实现这一点?
编辑: 例如:如果我有 [Authorize(Policy = "Policy 1")]
和 [Authorize(Policy = "Policy 2")]
并且只有“策略 2”失败。我希望看到一些信息告诉我是“策略 2”失败了。
编辑: 对于仍然遇到此问题的任何人,此问题现在已由 Microsoft 实施并且是 .NET 5.0 的一部分,请参阅问题 https://github.com/aspnet/AspNetCore/issues/7789
你可以在里面处理和记录这个 Middlewares
public class AuthHandlerMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ErrorHandlingMiddleware> _logger;
public AuthHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context, IHostingEnvironment env /* other scoped dependencies */)
{
await _next(context);
if (context.Response.StatusCode == 401)
_logger.LogInformation($"'{context.User.Identity.Name}' is unauthorized");
}
}
在您的启动配置中,
public void Configure(IApplicationBuilder app, ... )
{
....
app.UseMiddleware<AuthHandlerMiddleware>();
}
对于 Roles
和 Policy
,它们被转换为 RolesAuthorizationRequirement
等要求或 MinimumAgeRequirement
等您的自定义要求。
对于 Authorization failed.
,这是由 DefaultAuthorizationService
在 AuthorizeAsync
中记录的,您可能无法获得像 Policy 1
和 Policy 2
这样的确切名称。您可以获得 Policy
的要求。
尝试检查以下解决方法是否符合您的要求。
实施自定义
DefaultAuthorizationService
public class CustomAuthorizationService : DefaultAuthorizationService, IAuthorizationService { private readonly AuthorizationOptions _options; private readonly IAuthorizationHandlerContextFactory _contextFactory; private readonly IAuthorizationHandlerProvider _handlers; private readonly IAuthorizationEvaluator _evaluator; private readonly IAuthorizationPolicyProvider _policyProvider; private readonly ILogger _logger; public CustomAuthorizationService(IAuthorizationPolicyProvider policyProvider , IAuthorizationHandlerProvider handlers , ILogger<DefaultAuthorizationService> logger , IAuthorizationHandlerContextFactory contextFactory , IAuthorizationEvaluator evaluator , IOptions<AuthorizationOptions> options) : base(policyProvider, handlers, logger, contextFactory, evaluator, options) { _options = options.Value; _handlers = handlers; _policyProvider = policyProvider; _logger = logger; _evaluator = evaluator; _contextFactory = contextFactory; } public new async Task<AuthorizationResult> AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerable<IAuthorizationRequirement> requirements) { if (requirements == null) { throw new ArgumentNullException(nameof(requirements)); } var authContext = _contextFactory.CreateContext(requirements, user, resource); var handlers = await _handlers.GetHandlersAsync(authContext); foreach (var handler in handlers) { await handler.HandleAsync(authContext); if (!_options.InvokeHandlersAfterFailure && authContext.HasFailed) { break; } } var result = _evaluator.Evaluate(authContext); if (result.Succeeded) { _logger.LogInformation($"Authorization is succeeded for { JsonConvert.SerializeObject(requirements) }" ); //_logger.UserAuthorizationSucceeded(); } else { //var r = result.Failure.FailedRequirements.Select(requirement => new { Requirement = requirement.GetType() }); var json = JsonConvert.SerializeObject(result.Failure.FailedRequirements); _logger.LogInformation($"Authorization is failed for { json }"); //_logger.UserAuthorizationFailed(); } return result; } }
替换内置
DefaultAuthorizationService
services.AddAuthorization(config => { config.AddPolicy("T1", policy => policy.AddRequirements(new MinimumAgeRequirement(21))); }); services.Replace(ServiceDescriptor.Transient<IAuthorizationService, CustomAuthorizationService>());
Microsoft 在 .NET 5.0 中默认实现此功能,请参阅相关 GitHub 问题了解详细信息和 PR 链接。