具有策略和角色的ASP.NET核心授权属性

chhkpiq4  于 2023-10-21  发布在  .NET
关注(0)|答案(1)|浏览(82)

我有一个ASP.NET Core 6.0项目,我使用2个身份验证方案。
其中一个身份验证方案是,默认为“JwtBearerounce.AuthenticationScheme
这只适用于基于角色的身份验证。
另一个是“自定义
“自定义”仅用于基于策略的身份验证。

.AddAuthentication(options =>
{
   options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
   options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
   options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
   .....
}
.AddJwtBearer("Custom", options =>
{
    .....
});

在那之后,我添加了一些范围到“自定义”政策。
我想与控制器联系;

[Authorize(AuthenticationSchemes =“Custom”,Policy =“RandomPolicyName”)]

  • 或 *
    [Authorize(Roles=“User”)]
  • 我知道我不能在同一个控制器上同时使用这两个,它不能工作,因为它必须传递两个authorize属性。那我该怎么做呢??***
utugiqy6

utugiqy61#

我解决了这个问题。这对我来说很有效,如果你看到任何问题或有任何其他想法,然后与我们分享:)

    • 授权属性 *
public class AuthorizeMultiplePolicyAttribute : TypeFilterAttribute
{
   public AuthorizeMultiplePolicyAttribute(string policies, bool IsAll) : base(typeof(AuthorizeMultiplePolicyFilter))
   {
       Arguments = new object[] { policies, IsAll };
   }
}
    • 策略过滤 *
public class AuthorizeMultiplePolicyFilter : IAsyncAuthorizationFilter
{
    private readonly IAuthorizationService _authorization;
    public string _policies { get; private set; }
    public bool _isAll { get; set; }
    public AuthorizeMultiplePolicyFilter(string policies, bool IsAll, IAuthorizationService authorization)
    {
        _policies = policies;
        _authorization = authorization;
        _isAll = IsAll;
    }

    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        var policys = _policies.Split(";").ToList();
        if (_isAll)
        {
            foreach (var policy in policys)
            {
                var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
                if (!authorized.Succeeded)
                {
                    context.Result = new ForbidResult();
                    return;
                }
            }
        }
        else
        {
            foreach (var policy in policys)
            {
                var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
                if (authorized.Succeeded)
                {
                    return;
                }
            }
            context.Result = new ForbidResult();
            return;
        }
    }
}
    • 添加策略 *
services.AddAuthorization(options =>
{

    options.AddPolicy("CatalogReadOrWrite", policy =>
    {
          policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
          policy.RequireAuthenticatedUser();
          policy.RequireAssertion(context => context.User.HasClaim(c =>
              (c.Type == "scope" && (c.Value == "catalog_writepermission" || c.Value == "catalog_readpermission"))
          ));
    });

    options.AddPolicy("CatalogReadUser", policy =>
    {
          policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
          policy.RequireAuthenticatedUser();
          policy.RequireAssertion(context => context.User.HasClaim(c =>
              (
                ((c.Type == "role" || c.Type == ClaimTypes.Role || c.Type == "Roles") && (c.Value == "User.Admin" || c.Value == "User.Normal"))
              )
          ));
      });
  });
}
  • 控制器部分
  • false参数表示如果其中一个策略通过,则授权
[AuthorizeMultiplePolicy("CatalogWrite;CatalogReadOrWrite", false)]
  public async Task<IActionResult> BlaBlaAsync([FromBody] BlaBla model)
  {

  }
  • true参数表示如果所有策略都通过,则授权
[AuthorizeMultiplePolicy("CatalogWrite;CatalogReadOrWrite", true)]
  public async Task<IActionResult> BlaBlaAsync([FromBody] BlaBla model)
  {

  }

相关问题