Как я могу увидеть, какой AuthorizeAttribute Failed ASP.NET Core - PullRequest
0 голосов
/ 19 февраля 2019

Я пытаюсь выяснить, есть ли простой способ заставить ASP.NET Core регистрировать, какой атрибут [Authorize] не работает.У меня есть смесь атрибутов авторизации "Роль" и "Политика", но всякий раз, когда один из них не проходит, журналы просто показывают:

enter image description here

Очевидно, что этоправильное поведение, и это не позволяет кому-то с неправильными разрешениями, однако, если у вас есть несколько атрибутов, то немного сложно найти и выяснить, какой из них потерпел неудачу.Если бы в журнале просто показывалось Authorization failed for Policy X, тогда было бы действительно легко найти причину сбоя.

Кто-нибудь знает, возможно ли в настоящее время сделать это с помощью какой-то опции, о которой я не знаю?

РЕДАКТИРОВАТЬ: Например: если у меня были [Authorize(Policy = "Policy 1")] и [Authorize(Policy = "Policy 2")] и только «Политика 2» не удалось.Я хотел бы увидеть кое-что, что говорит мне, что это «Политика 2» потерпела неудачу.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Для Roles и Policy они переводятся в соответствии с требованиями RolesAuthorizationRequirement или вашими требованиями, например MinimumAgeRequirement.

Для Authorization failed. это записывается как DefaultAuthorizationService в AuthorizeAsync, вы не можете получить точное имя, например Policy 1 и Policy 2.Вы можете получить требования для Policy.

Попробуйте проверить, соответствует ли приведенный ниже обходной путь вашему требованию.

  1. Реализация пользовательского 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 successed for { result.Failure.FailedRequirements }" );
                //_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;
        }
    
    }
    
  2. Заменить встроенным-в DefaultAuthorizationService

    services.AddAuthorization(config =>
    {
        config.AddPolicy("T1", policy => policy.AddRequirements(new MinimumAgeRequirement(21)));
    });
    
    services.Replace(ServiceDescriptor.Transient<IAuthorizationService, CustomAuthorizationService>());
    
0 голосов
/ 19 февраля 2019

вы можете обрабатывать и регистрировать это внутри 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>();
}
...