AuthorizeAttribute на BaseController HttpContext.User.Identity.Name в политике отсутствует - PullRequest
0 голосов
/ 03 мая 2018

В моем основном веб-API asp.net я хочу быть уверен, что пользователи действительно существуют и не деактивируются при вызове некоторых действий. Мы используем аутентификацию JwtBearer, что работает довольно хорошо. Наша проблема заключается в том, что при использовании только Microsoft.AspNetCore.Authorization.AuthorizeAttribute не имеет значения, был ли пользователь удален или деактивирован после выдачи токена (если токен сам по себе действителен).

В моем Startup.cs я настроил политику для решения этой проблемы:

     services.AddAuthentication(options =>
       {
           options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
       }).AddJwtBearer(options =>
       {
           options.TokenValidationParameters = AuthenticationHandler.TokenValidationParameters;
       });
       services.AddAuthorization(options =>
       {
           options.DefaultPolicy = new AuthorizationPolicyBuilder(
                                     JwtBearerDefaults.AuthenticationScheme)
               .RequireAuthenticatedUser()
               .Build();
           options.AddPolicy(nameof(ExistingUserRequirement), 
                   policy => policy.Requirements.Add(new ExistingUserRequirement()));
       });
       services.AddTransient<IAuthorizationHandler, ExistingUserHandler>();

Там я запрашиваю DataContext, если пользователь существует и активен. Что работает: Если я настрою атрибут Authorization для действия, все будет работать нормально:

[HttpPost]
[Authorize(Policy = nameof(ExistingUserRequirement))]
public JsonResult Post([FromBody]CreateStoryViewModel viewModel) { ...}

Я могу получить доступ к идентификационной информации пользователя, используя HttpContextAccessor.HttpContext.User.Identity.Name.

Что не работает: Если я настраиваю атрибут на моем BaseController, при запуске ExistingUserHandler контекст Identity-контекста кажется отсутствующим:

[Authorize(Policy = nameof(ExistingUserRequirement))]
public abstract class BaseController : Controller { ... }

Теперь Identity.Name возвращается всегда NULL:

public class ExistingUserHandler : AuthorizationHandler<ExistingUserRequirement>
{
    private IHttpContextAccessor HttpContextAccessor { get; }

    private SaycleContext SaycleContext { get; }

    public ExistingUserHandler(IHttpContextAccessor httpContextAccessor, SaycleContext saycleContext)
    {
        HttpContextAccessor = httpContextAccessor;
        SaycleContext = saycleContext;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext authorizationContext, ExistingUserRequirement requirement)
    {
        var exists = false;
        if (Guid.TryParse(HttpContextAccessor.HttpContext.User.Identity.Name, out var currentUserId))
        {
            exists = SaycleContext.Users.Any(u => Equals(u.Id, currentUserId));
        }
        if (!exists)
        {
            throw new NonExistingUserException();
        }
        authorizationContext.Succeed(requirement);
        return Task.CompletedTask;
    }
}

Я что-то упустил? Почему контекст идентичности не может быть разрешен с помощью атрибута Authorize моего родителя BaseController?

...