将参数从控制器传递到自定义AuthorizationHandler

时间:2020-03-31 18:54:09

标签: authentication .net-core authorization

我正在使用一种控制器,允许人们共享访问权限以更新网站。我正在尝试使用AuthorizationHandler来验证当前用户是否有权更新他们正尝试更新的网站。

我当前的Request和AuthorizationHandler

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创建动态的策略,如下所示

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 个答案:

答案 0 :(得分:1)

如果您尝试通过HTTP请求传递值,则可以通过传递到处理程序(source)的Resource上的AuthorizationHandlerContext属性访问这些值。 / p>

如果您只是尝试传递某种配置类型设置,请确保您的AuthorizationHandler具有生命周期Transient并将这些值传递给构造函数。

相关问题