Передать параметр из контроллера в пользовательский AuthorizationHandler - PullRequest
0 голосов
/ 31 марта 2020

Я работаю над контроллером, который позволяет людям делиться доступом к обновлению сайта. Я пытаюсь работать с AuthorizationHandler, который проверяет, есть ли у текущего пользователя доступ к обновлению веб-сайта, который он пытается обновить.

Мой текущий запрос и AuthorHandler

public class WebsiteRequirement : IAuthorizationRequirement
{
    public WebsiteRequirement(int websiteId)
    {
        WebsiteId = websiteId;
    }

    public int WebsiteId { get; private set; }

}
internal class WebsiteAuthorizationHandler : AuthorizationHandler<WebsiteRequirement>, IAuthorizationHandler
{
    private readonly IWebsiteLogic _websiteLogic;

    public WebsiteAuthorizationHandler(IWebsiteLogic websiteLogic)
    {
        _websiteLogic = websiteLogic;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, WebsiteRequirement requirement)
    {
        int userId = int.Parse(context.User.FindFirst(c => c.Type == "UserId").Value);

        // Use the _websiteLogic to check if user has access, based on user id and website Id
        if(_websiteLogic.CheckUserAccess(userId, requirement.WebsiteId)){
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }
        return Task.CompletedTask;
    }
}

Я знаю, что вы можете использовать AuthorizationHandler для создания политик, которые довольно динамичны c, как показано ниже

public void ConfigureServices(IServiceCollection services)
{
  services.AddAuthorization(options =>
  {
      options.AddPolicy("WebAuth", policy => policy.Requirements.Add(new WebsiteRequirement(1)));
  });

    services.AddSingleton<IAuthorizationHandler, WebsiteAuthorizationHandler>();
}

Но можно ли передать это 1 из контроллера? Я не хочу создавать новую политику для каждого нового веб-сайта (я также хочу повторно использовать эту аналогичную структуру для множества других аналогичных случаев использования. Мое последнее средство - иметь SecurityService, который я вызываю при каждом вызове из контроллер, но это действительно не выглядит элегантно, но я также не видел ничего, что позволяло бы то, что я пытаюсь сделать.

[HttpPost]
[Authorize(Policy = "WebAuth", WebsiteId=[FromBody]website.id)]  // Trying to do something like this
public ActionResult<WebsiteDto> SaveWebsite([FromBody] WebsiteDto website)
{
    if(_websiteLogic.CheckUserAccess(CurrentUserId, website.Id)) // My Backup Solution
    {
        return _websiteLogic.AddWebsite(website);
    }
    return new UnauthorizedResult();
}

1 Ответ

1 голос
/ 31 марта 2020

Если вы пытаетесь передать значения из HTTP-запроса, вы можете получить доступ к этим значениям с помощью свойства Resource в AuthorizationHandlerContext, переданном в обработчик ( source ).

Если вы просто пытаетесь передать какую-либо настройку типа конфигурации, убедитесь, что у вашего AuthorizationHandler есть время жизни Transient, и передайте эти значения в конструкторе.

...