Role/Group 在 ASP.NET 中使用 Auth0 授权

Authorization by Role/Group in ASP.NET using Auth0

在此先感谢您对此事的帮助!

我希望有人能帮我弄清楚如何按 Auth0 授权扩展中分配的组授权 API 访问。

我目前在 Web api 中完美地使用 [Authorize] 属性 - 如果他们已成功登录,它允许 api 调用,否则阻止它。

但是,如果我尝试 [Authorize(Roles = "myGroupName")] 授权失败。如果我在 Auth0 网站的用户仪表板中手动将其添加到用户 app_metadata 而不是通过扩展分配,也会发生同样的情况。

我的项目是按照 Angular 快速入门和 Asp.Net 快速入门设置的。我验证令牌服务器端的 webapiconfig 是:

 class WebApiConfig
{
    public static void Register(HttpConfiguration configuration)
    {
        var clientID = WebConfigurationManager.AppSettings["auth0:ClientId"];
        var clientSecret = WebConfigurationManager.AppSettings["auth0:ClientSecret"];

        configuration.MessageHandlers.Add(new JsonWebTokenValidationHandler()
        {
            Audience = clientID,
            SymmetricKey = clientSecret
        });

        configuration.Routes.MapHttpRoute("API Default", "api/{controller}/{id}",
            new { id = RouteParameter.Optional });
    }
}

我无权发表评论,所以我要从这里询问。你为什么要这样做

[Authorize(Roles = "myGroupName")] 

据我所知,当我实施基于组的授权时,我仍在输入

[Authorize(Roles = "myRoleName")] 

不是其他方式。

Auth0 Authorization 扩展目前支持通过组概念进行授权决策。您可以创建一个组,将用户分配到该组,并将应用程序配置为仅供特定组内的用户访问。所有这些都将自动处理,应用程序预期组之外的任何用户都将被拒绝完全访问。

您的用例有点不同,但仍然有效。您希望使用扩展配置的组与生成的令牌一起发送,以便应用程序本身根据这些值做出授权决策。

为了在令牌中发送在扩展中配置的组,您需要做的第一件事就是请求它们。为此,您需要在执行身份验证请求时包含 groups 范围。

Add the user's group membership to the outgoing token (which can be requested via the OpenID groups scope);

(重点是我的,来源:Authorization Extension Docs,第 规则行为

如果您使用该范围请求令牌,然后在 jwt.io 中对其进行解码,您将得到类似的内容(实际组因用户而异):

{
  "groups": [
    "GROUP-1",
    "GROUP-2"
  ],
  "iss": "https://[tenant].auth0.com/"
}

现在,在 ASP .NET API 端验证此信息。假设您使用的示例是这个 (ASP.NET Web API),令牌中包含的组信息将映射到以下声明:

  • 类型:groups |值:GROUP-1
  • 类型:groups |值:GROUP-2

发生这种情况是因为 JsonWebToken class 中存在的逻辑通过创建共享相同类型的按值声明来处理来自 JWT 负载的数组。

最后一部分是确保 AuthorizeAttribute 检查这些 groups 类型的声明,而不是尝试查找角色声明。您应该能够完成此操作,方法是将 JsonWebToken class 中的 RoleClaimType 常量更改为具有值 "groups" 而不是 "http://schemas.microsoft.com/ws/2008/06/identity/claims/role".

如您所知,Authorize 属性使用主体中的内容工作:继承 IPrincipal 的内容。 在网络api中,它更具体;它是继承ClaimsPrincipal的东西(这个自己实现IPrincipal)。 您肯定已经知道,声明就像一个键值对。 ClaimsPrincipal 包含一系列直接从身份验证令牌中获取的键值对。此身份验证令牌大部分时间由身份验证服务器颁发为 JWT(Json Web 令牌)。大多数时候,身份验证服务器也在使用 OAuth,就像你的情况一样。 如果您希望在您的应用程序中扮演角色的用户组无法使用开箱即用的 Authorize 属性,那是因为它没有正确映射:Auhtorize checks the claim with claim类型:http://schemas.microsoft.com/ws/2008/06/identity/claims/role("claim type" 是键值对的 "key")。这意味着如果你想让你的 Authorize 发挥作用,这个声明必须与团队一起评估。 您可以做几件事来在您的应用程序中获得干净的授权。

  • 制作自定义 Authorize 属性。此 Authorize 属性将检查使用不同声明类型的角色。引用用户组的声明类型取决于您的身份验证服务器。如果您在身份验证服务器的文档中找不到用于组的声明类型,运行 调试您的应用程序,并检查 属性 User 中包含的每个声明你的控制器。您一定会找到您感兴趣的索赔类型。
  • 通过重新定义用户信息与生成的令牌的声明之间的映射来更改授权服务器的设置(在您的情况下,将用户组映射到类型为 http://schemas.microsoft.com/ws/2008/06/identity/claims/role 的声明) .通常,这可以针对每个客户端应用程序甚至全局进行设置。例如,如果您使用 ADFS 身份验证、AzureAD 或 WSO2 身份验证服务器 (http://wso2.com/products/identity-server/)
  • ,则必须采用这种方式
  • 添加一个owin中间件来修改当前主体。它将通过将包含组的声明的值复制到声明类型 http://schemas.microsoft.com/ws/2008/06/identity/claims/role 来更改当前主体。这个中间件必须在认证中间件之后的流程中插入