【问题标题】:Auth0, with Authorization Extension & ASP.NET AuthorizationAuth0,带有授权扩展和 ASP.NET 授权
【发布时间】:2019-02-04 05:59:44
【问题描述】:

我正在使用 Auth0 进行项目。我们希望使用授权扩展中的权限系统来设置它。

例如 角色管理员: 用户:查看全部 用户:编辑 用户:xyz

角色用户: 用户:editOwn 用户:viewOwn 用户:等

如果可能,然后在项目中使用[Authorize(Policy = "users:kvm")] 标签。

但是,我找不到任何有关如何从 Auth0 实际使用授权扩展的资源。我完全不知所措,所以如果有人能指导我在哪里寻找这些,我会很高兴。

【问题讨论】:

    标签: c# asp.net-core auth0


    【解决方案1】:

    您可以使用 Authorization Extension 创建代表对每个应用程序的访问权限的权限。

    注意:创建权限时“名称”应反映应用程序的客户端 ID

    下面的示例图片

    然后创建代表每个应用程序的角色并确保选择了相关权限。

    在本例中:角色名称为“SampleClientAccess”

    1. 然后创建组并链接您创建的角色。将相关用户添加到群组

    1. 最后一步。转到仪表板 > 规则 > 创建自定义规则和以下代码。

    function (user, context, callback) { 
          // Assume that permission for an application is the client_id of the permission then
     
         if (user.permissions.indexOf(context.clientID) === -1 ){
             callback(new UnauthorizedError('You are not allowed to access ' + context.clientName + JSON.stringify(user)));
         }
         callback(null, user, context);
    }

    希望这会对您有所帮助。

    【讨论】:

    • 不完全是我想要的。我的想法是,在 Auth0 授权扩展中设置权限,例如:editOtherAccount - 然后在我的应用程序中执行:If(LoggedIn.HasPermission("editOtherAccount")) 等。现在的主要问题是用户必须注销,然后在更新权限之前重新登录,所以如果我对用户进行降级,它不会立即影响他们
    【解决方案2】:

    授权扩展可通过API访问

    您必须启用 API 访问并设置机器对机器的通信,以便您可以访问端点。 (如链接中所述)

    然后使用this文档来管理权限、角色、组等。

    每个请求都必须包含一个令牌 (JWT),您必须事先通过 POST 请求从 https://yourdomain.auth0.com/oauth/token 获取该令牌。

    你必须提供四个参数:

    grant_type = client_credentials 
    client_id = {from your auth0 application}
    client_secret = {from your auth0 application}
    audience=urn:auth0-authz-api
    

    将令牌作为"Authorization" : "Bearer #YOURTOKEN#"放入每个请求的标头中

    您可以使用任何 REST 客户端来访问端点。首先,我建议Postman 测试端点并检查您需要哪些调用。有一个方便的collection,您可以通过一些调整来使用。

    【讨论】:

      【解决方案3】:

      我决定放弃 auth0 的授权并自己制定一个系统。

      无法理解文档。

      【讨论】:

        【解决方案4】:

        我想添加我在旧版 .NET MVC 应用程序和 .NET Core 2.0 API 中的使用方式,因为我希望它可以为我节省大量时间来解决这个问题。

        如果您想要的只是在 auth0 中获取组、权限、角色和更新用户帐户,请按照@StV 的答案中的步骤操作。

        但是,如果您想在 .NET 中检查权限/角色等,那么我就是这样做的:

        将组、角色和权限添加到访问或 Id 令牌(或两者)。要做到这一点,请按照说明here

        一旦您从上述配置步骤发布规则,您必须自己在 Auth0 中创建另一个规则,以将信息复制到令牌中(这让我有一段时间)。这必须在 Auth0 发布/创建的规则之后运行。我的看起来像这样:

        function (user, context, callback) {
          if(user.app_metadata) {
            var namespace = 'https://visionplatform.com/';
            context.accessToken[namespace + 'roles'] = user.roles;
            context.accessToken[namespace + 'permissions'] = user.permissions;
            context.idToken[namespace + 'roles'] = user.roles;
            context.idToken[namespace + 'permissions'] = user.permissions;    
          }
          callback(null, user, context);
        }
        

        现在,如果您的用户登录,他们将在其令牌中拥有自己的组、角色和权限。但是请记住,您通过身份验证的特定客户端的组、角色和权限会显示(我为此浪费了几个小时)。

        所以现在您可以在解码 JWT 的代码中获取/检查权限。这是我在库方法中如何完成此操作的一些 sn-ps 代码(即不是授权属性):

        首先获取您的 TokenValidationPrams

        public TokenValidationParameters GetTokenValidationParameter(string domain, string audience)
        {
            IConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{domain}.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
            var openIdConfig = AsyncHelper.RunSync(async () => await configurationManager.GetConfigurationAsync(CancellationToken.None));
        
            return new TokenValidationParameters
            {
                ValidIssuer = $"{domain}",
                ValidAudiences = new[] { audience },
                IssuerSigningKeys = openIdConfig.SigningKeys
            };
        }
        

        然后解码您的 JWT 以获取声明

        private ClaimsPrincipal GetValidatedToken(string token, TokenValidationParameters validationParameters)
        {
            var handler = new JwtSecurityTokenHandler();
            return handler.ValidateToken(token, validationParameters, out var _);
        }
        

        现在您可以检查声明原则以查看它是否包括您的组、权限或其他内容(请注意,我只是检查权限)。

        public bool ValidateTokenClaimsPermissionExists(string token, string domain, string audience, string permission)
        {
            var claimsPrincipal = GetValidatedToken(token, _tokenValidationParameters);
        
            var scopePermission = claimsPrincipal.FindFirst(c => c.Type == Constants.PermissionsClaimTypeName && c.Value == permission);
            return scopePermission != null;
        }
        

        我使用上面的方法进行单独的调用来检查权限,但是您可以(并且可能应该)编写自己的授权属性,或者如果您使用 .NET Core,您可以编写一个 AuthorizationHandler 中间件来检查您想要的任何声明文档here。下面的一个检查范围,但您可以根据上面的代码对其进行调整以检查权限:

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasScopeRequirement requirement)
        {
            // If user does not have the scope claim, get out of here
            if (!context.User.HasClaim(c => c.Type == "scope" && c.Issuer == requirement.Issuer))
            {
                return Task.CompletedTask;
            }
        
            // Split the scopes string into an array
            var scopes = context.User.FindFirst(c => c.Type == "scope" && c.Issuer == requirement.Issuer).Value.Split(' ');
        
            // Succeed if the scope array contains the required scope
            if (scopes.Any(s => s == requirement.Scope))
                context.Succeed(requirement);
        
            return Task.CompletedTask;
        }
        

        我也将使用上述所有内容为我的 .NET MVC 应用程序编写授权属性。

        【讨论】:

          【解决方案5】:

          对于简单的设置,您可以通过 Auth0 GUI 设置角色并使用规则将其应用于用户:

          function (user, context, callback) {
          
             // Roles should only be set to verified users.
            if (!user.email || !user.email_verified) {
              return callback(null, user, context);
            }
          
            user.app_metadata = user.app_metadata || {};
          
            const assignedRoles = (context.authorization || {}).roles;
          
            const addRolesToUser = function(user) {
              return assignedRoles;
            };
          
            const roles = addRolesToUser(user);
          
            user.app_metadata.roles = roles;
            auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
              .then(function() {
                context.idToken['https://schemas.<yourdomain>.com'] = user.app_metadata.roles;
                callback(null, user, context);
              })
              .catch(function (err) {
                callback(err);
              });
          }
          

          你的 startup.cs 应该是这样的:

          services.AddAuthorization(options =>
          {
            options.AddPolicy("Administrator", authBuilder => { authBuilder.RequireRole("Administrator"); });
            options.AddPolicy("User", authBuilder => { authBuilder.RequireRole("Administrator", "User"); });
          }
          

          以控制器为例:

          [Authorize(Roles = "Administrator, User")]
          <<your code>>
          

          【讨论】:

            猜你喜欢
            • 2016-12-17
            • 2017-06-08
            • 2018-08-16
            • 1970-01-01
            • 1970-01-01
            • 2018-10-25
            • 2020-03-28
            • 2020-06-23
            • 1970-01-01
            相关资源
            最近更新 更多