使用 Auth0 在 ASP.NET 中按角色/组进行授权

Posted

技术标签:

【中文标题】使用 Auth0 在 ASP.NET 中按角色/组进行授权【英文标题】:Authorization by Role/Group in ASP.NET using Auth0 【发布时间】:2017-02-09 23:24:38 【问题描述】:

提前感谢您在这件事上的帮助!

我希望有人能帮我弄清楚如何按在 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 );
    

【问题讨论】:

感谢任何帮助。 JsonWebTokenValidationHandler 类默认不添加 Claim 角色。看这个帖子auth0.com/forum/t/… 【参考方案1】:

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

[Authorize(Roles = "myGroupName")] 

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

[Authorize(Roles = "myRoleName")] 

别无他法。

【讨论】:

嘿伙计,别担心 - 我收到评论了。我已经尝试过 - 在应用程序元数据中手动分配角色并使用组的授权扩展。但是,当使用 Auth0 处理令牌时,两者都显示为“组”声明。【参考方案2】:

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

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

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

将用户的组成员身份添加到传出令牌(可以通过 OpenID 组范围请求);

(重点是我的,来源: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 类中存在的逻辑,该类通过创建共享相同类型的按值声明来处理来自 JWT 有效负载的数组。

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

【讨论】:

我开始不依赖第三方,但感谢您抽出宝贵时间回答。我觉得这最好地解决了所提出问题的多个方面。 想要添加有关如何添加到请求的更多详细信息。这就是我让它工作的方式。 // 配置 Auth0 lock = new Auth0Lock(myConfig.clientID, myConfig.domain, auth: params: scope: 'openid groups', );【参考方案3】:

正如您肯定知道的那样,Authorize 属性使用主体中的内容工作:继承 IPrincipal 的内容。 在web api中,更加具体;它继承了ClaimsPrincipal(这实现了自己IPrincipal)。 正如您已经知道的那样,声明就像一个键值对。 ClaimsPrincipal 包含一系列直接取自身份验证令牌的键值对。此身份验证令牌大部分时间由身份验证服务器作为 JWT(Json Web 令牌)颁发。大多数时候,身份验证服务器也使用 OAuth,就像您的情况一样。 如果您希望在应用程序中扮演角色的用户组无法通过使用开箱即用的 Authorize 属性工作,那是因为它没有正确映射:Auhtorize 使用声明类型检查声明: http://schemas.microsoft.com/ws/2008/06/identity/claims/role(“声明类型”是键值对的“键”)。这意味着,如果您希望您的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 来更改当前主体。此中间件必须在身份验证中间件之后插入流中

【讨论】:

以上是关于使用 Auth0 在 ASP.NET 中按角色/组进行授权的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 MVC for Asp.NET 中使用 Outlook 电子邮件组作为角色?

使用 Active Directory 中的安全组的 Asp.Net 基于角色的身份验证

通过 Auth0 React 和 ASP.net 核心授权然后使用 JWT 令牌

Auth0 - 规则 & 组 && 用户管理

向用户 ASP.NET 身份添加自定义角色

将新的 ASP.NET MVC 应用程序与现有角色集成