【问题标题】:IdentityServer: Multiple Clients with different grant types, policies not working properlyIdentityServer:具有不同授权类型的多个客户端,策略无法正常工作
【发布时间】:2020-06-17 06:48:06
【问题描述】:

我有一个身份服务器设置,具有以下“看起来像”配置:

        return new List<Client>
        {
            new Client
            {
                [...]
                AllowedGrantTypes = GrantTypes.Implicit,
                [....]
            },
            new Client
            {
                [...]
                AllowedGrantTypes = GrantTypes.ClientCredentials,
                [....]
            }
        };

和这样注释的控件:

    [Route("api/forms")]
    [ApiController]
    [Authorize(Policy = "user.api.portfolio.manager")]
    [Authorize(Policy = "application.api.portfolio.manager")]
   public class FormsController : ControllerBase
   {
      [...]
   }

和政策

        private System.Action<AuthorizationOptions> AddJwtAuthorizationPolicyForRole()
        {
            return options => { options.AddPolicy("**POLICY_FOR_GRANT_IMPLICIT**", policy => { 
                policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme); 
                policy.RequireAuthenticatedUser();
                policy.RequireClaim(ClaimTypes.Role, "USER_ACCESSIBLE");
            }); 
            };
        }

        private System.Action<AuthorizationOptions> AddJwtAuthorizationPolicyForRole()
        {
            return options => { options.AddPolicy("**POLICY_FOR_CLIENT_CREDENTIALS**", policy => { 
                policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme); 
                policy.RequireAuthenticatedUser();
            }); 
            };
        }

所以我想实现:

使用 GrantType.ClientCredentials 的客户端无需任何进一步的需求即可访问控制器。 使用隐式模式的客户端必须具有角色 USER_ACCESSIBLE

如果配置如上所示,则必须应用两种策略 -> 两种授权类型均失败。

如何使用 IdentityServer 实现所描述的行为,每个授权类型可能有一个独立的策略以便应用?

提前感谢您的帮助。

【问题讨论】:

    标签: c# .net asp.net-core identityserver4 policies


    【解决方案1】:

    最简单的解决方案是为 Implicit + ClientCredential 添加另一个单一策略来实现 OR 条件的逻辑。

    或者您可以创建一个自定义属性,例如:

    • MultiplePolicysAuthorizeAttribute

      public class MultiplePolicysAuthorizeAttribute : TypeFilterAttribute
      {
           public MultiplePolicysAuthorizeAttribute(string policys, bool isAnd = false) : base(typeof(MultiplePolicysAuthorizeFilter))
           {
               Arguments = new object[] { policys, isAnd };
           }
      }
      
    • MultiplePolicysAuthorizeFilter

      public class MultiplePolicysAuthorizeFilter : IAsyncAuthorizationFilter
      {
          private readonly IAuthorizationService _authorization;
          public string Policys { get; private set; }
          public bool IsAnd { get; private set; }
      
          public MultiplePolicysAuthorizeFilter(string policys, bool isAnd, IAuthorizationService authorization)
          {
             Policys = policys;
             IsAnd = isAnd;
             _authorization = authorization;
          }
      
          public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
          {
              var policys = Policys.Split(";").ToList();
              if (IsAnd)
              {
                  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;
              }
           }
      }
      

    如果操作需要匹配策略之一(OR):

    [MultiplePolicysAuthorize("POLICY_FOR_GRANT_IMPLICIT;POLICY_FOR_CLIENT_CREDENTIALS")]
    

    如果操作需要匹配所有策略(和):

    [MultiplePolicysAuthorize("POLICY_FOR_GRANT_IMPLICIT;POLICY_FOR_CLIENT_CREDENTIALS",true)]
    

    代码示例参考:https://stackoverflow.com/a/52639938/5751404

    【讨论】:

    • 非常感谢您的帮助!它似乎正在工作。但是没有任何内置方法可以实现这种行为 - 因为我的问题似乎很常见。
    • 不,没有内置选项可以做到这一点,或者您可以在一个要求中使用多处理程序:docs.microsoft.com/en-us/aspnet/core/security/authorization/…
    • hmm,无法让 MultiplePolicyAuthorize 实现工作,我的用户对象在调用期间没有(还没有?)设置 - 还有其他步骤吗?
    • 无其他步骤并确认 1.您正确设置了策略 2.正确使用 AddJwtBearer 扩展来验证令牌并创建用户原理 3.设置 app.UseAuthentication(); app.UseAuthorization();在配置方法中
    猜你喜欢
    • 2020-08-06
    • 2021-07-30
    • 2023-04-03
    • 1970-01-01
    • 2018-02-07
    • 2017-08-17
    • 1970-01-01
    • 2016-05-20
    • 2020-07-14
    相关资源
    最近更新 更多