C# 我应该如何使用Azure AD SSO处理应用内权限?

C# 我应该如何使用Azure AD SSO处理应用内权限?,c#,asp.net-core,azure-active-directory,adal,C#,Asp.net Core,Azure Active Directory,Adal,第一个项目同时使用single sign-on和Azure,所以可能我做得不对。在使用SSO之前,我将自己生成令牌。这允许我在令牌中放入我想要的任何内容,我将使用它来确定权限。使用react adal和Azure AD SSO,令牌在客户端生成,我得到的只是用户身份。按照我过去所做的,我编写了一个自定义属性,以确保用户具有API调用的适当权限。但是,除了从每个请求传递的令牌中提取信息之外,我还必须在他们每次发出请求时查询权限,这实际上是数据库命中率的两倍 我是否有办法使用单一登录和应用程序驱动的

第一个项目同时使用single sign-on和Azure,所以可能我做得不对。在使用SSO之前,我将自己生成令牌。这允许我在令牌中放入我想要的任何内容,我将使用它来确定权限。使用react adal和Azure AD SSO,令牌在客户端生成,我得到的只是用户身份。按照我过去所做的,我编写了一个自定义属性,以确保用户具有API调用的适当权限。但是,除了从每个请求传递的令牌中提取信息之外,我还必须在他们每次发出请求时查询权限,这实际上是数据库命中率的两倍

我是否有办法使用单一登录和应用程序驱动的权限来处理角色/权限(管理员、经理、用户、只读等),而无需在每次需要检查权限时查询数据库

以前的程序:
用户访问站点>输入凭据>服务器验证、获取权限、生成具有权限的令牌、将其返回给客户端>客户端在每个请求上传递令牌>服务器验证和解析令牌>属性检查解析的令牌以确保用户具有必要的权限>完成请求

当前过程:
用户访问站点>客户端使用Azure AD进行身份验证并获取令牌>客户端在每个请求上传递令牌>服务器从令牌获取身份验证信息>服务器查询数据库以获取用户权限>属性检查查询结果以确保用户具有必要的权限>完成请求


如何使当前流程更好?我发现的每一个谷歌结果都只涉及身份验证,并没有深入到实际应用程序中,让我找到“最佳实践”甚至任何实践。我只是做错了吗?

请查看Azure AD的应用程序角色相关功能,以实现自定义RBAC。它应该为您所提到的内容提供一个良好的起点,因为角色集合将作为来自Azure AD的传入令牌的一部分提供给您

应用程序角色 Microsoft文档-

目的-这些角色在应用程序清单中为组织正在开发并在Azure Active Directory中注册的应用程序定义。这些角色非常特定于您的应用程序,可以在应用程序的代码中用于为经过身份验证的用户实现授权逻辑

示例应用程序(使用此概念并实现所需功能)-

快速解释

1) 在Azure AD中注册应用程序后,您可以通过在Azure AD中编辑应用程序清单(JSON)来定义自定义角色(特定于您的应用程序)。
下面是应用程序角色定义的示例JSON:

"appRoles": 
[
  {
    "allowedMemberTypes": [
      "User"
    ],
    "description": "Creators can create Surveys",
    "displayName": "SurveyCreator",
    "id": "1b4f816e-5eaf-48b9-8613-7923830595ad",
    "isEnabled": true,
    "value": "SurveyCreator"
  },
  {
    "allowedMemberTypes": [
      "User"
    ],
    "description": "Administrators can manage the Surveys in their tenant",
    "displayName": "SurveyAdmin",
    "id": "c20e145e-5459-4a6c-a074-b942bbd4cfe1",
    "isEnabled": true,
    "value": "SurveyAdmin"
  }
]
2) 您将能够通过Azure Portal或以编程方式将这些角色分配给用户/组/应用程序。(您可以控制角色允许的成员类型)

3) 现在,当最终用户登录到您的应用程序时,传入的Azure AD令牌将为您提供一组角色声明(基于分配给用户的任何角色),您可以在应用程序中做出授权决策

if (context.User.HasClaim(ClaimTypes.Role, "Admin")) { ... }
以下是有关Microsoft文档的另一个相关文档-

我看到您在问题中也标记了asp.net-core。所以,如果您使用的是ASP.NET核心应用程序,您可能会使用上面链接部分所示的策略

public class SurveyCreatorRequirement : AuthorizationHandler<SurveyCreatorRequirement>, IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SurveyCreatorRequirement requirement)
    {
        if (context.User.HasClaim(ClaimTypes.Role, Roles.SurveyAdmin) ||
            context.User.HasClaim(ClaimTypes.Role, Roles.SurveyCreator))
        {
            context.Succeed(requirement);
        }
        return Task.FromResult(0);
    }
}
公共类调查CreatorRequirement:AuthorizationHandler,IAAuthorizationRequirement
{
受保护的覆盖任务HandleRequirementAsync(授权HandlerContext上下文、SurveyCreator请求要求)
{
if(context.User.HasClaim(ClaimTypes.Role,Roles.SurveyAdmin)||
context.User.HasClaim(ClaimTypes.Role,Roles.SurveyCreator))
{
成功(要求);
}
返回Task.FromResult(0);
}
}

另一方面,我看到过这样的情况:人们根据用户所属的组选择执行一些授权逻辑。这只是信息,不是你需要做的事情。在这个回答中,我将分享一些关于角色和组的详细信息,但一定要先看看应用程序角色。您甚至可以在授权策略中同时使用角色和组

组 组可以有多个用户或其他组作为成员。同样,可以通过Azure门户或编程方式管理组

注意:组完全独立于您的应用程序,即Azure广告组可以而且确实存在,以便在没有应用程序的情况下对成员进行分组。另一方面,应用程序角色对于您的应用程序非常特定,它们对除您的应用程序之外的任何人都没有多大意义

if (context.User.HasClaim(ClaimTypes.Role, "Admin")) { ... }
基于群组做出决策的示例应用程序


单个或特定的基于资源的授权 还要知道,当涉及到单个基于资源的授权(而不是更通用的基于角色的授权)时,您无论如何都需要转到数据库或其他持久性存储,因为这是唯一知道系统中权限和单个对象之间详细映射的地方


我在一篇相关的SO帖子中对此进行了讨论-

我认为这是正确的,因为应用程序中的角色模型可能与AAD不同。如果担心性能冲击数据库,将RIDIS缓存放在中间