如何基于.net核心应用程序中的组进行授权?

问题描述 投票:0回答:1

网络核心应用程序。我的要求是添加基于组的授权。我是Azure AD的用户。我属于以BR和AR开头的一些组名。仅属于AR组的用户应该能够访问我的API。当前,我的客户端应用程序是Swagger,我只能通过swagger来访问APIS。

例如,在启动时,我可以输入以下代码。

services.AddAuthorization(options => {
                options.AddPolicy("AR-BitBucket-User",
                        policyBuilder => policyBuilder.RequireClaim("groups",
                        "6be4f534-dcf5-489e-b57d-c7bb46be8d6b"));
            });  

在控制器中,

[Authorize("AR-BitBucket-User")]

在上述方法中,我正在硬编码,但是我不想硬编码。首先,我没有在JWT令牌中获得组信息,而我正在获得

hasGroups:true在我的JWT令牌中。与其进行硬编码,不如从Graph API获得它。有人可以帮我怎么做吗?我无法在互联网上获得任何相关示例。有人可以帮我吗?

c# asp.net-core azure-active-directory authorization
1个回答
0
投票

如果要配置您的应用程序以接收团体索赔,则需要在清单文件中将“ groupMembershipClaims”值设置为SecurityGroup

  1. 在“应用程序注册门户”的应用程序设置页面中,单击“清单”以打开嵌入式清单编辑器。

  2. 通过查找“ groupMembershipClaims”设置来编辑清单,并将其值设置为“ SecurityGroup”。

  3. 保存清单。

    {
      ...
      "errorUrl": null,
      "groupMembershipClaims": "SecurityGroup",
      ...
    }

当为应用程序启用组声明时,Azure AD在JWT和SAML令牌中包括一个声明,该声明包含用户所属的所有组的对象标识符(objectId),包括传递组成员身份。

但是请注意,请确保令牌大小不超过HTTP标头大小限制,Azure AD限制了它的objectId数量包括在团体索赔中。如果用户是多个组的成员超额限制(SAML令牌为150,JWT令牌为200),然后Azure AD不会发出令牌中的组声明。相反,它在令牌中包含超额索偿要求,以表明应用程序以查询Graph API来检索用户的组成员资格。有关更多详细信息,请参阅blog

enter image description here

关于如何基于该组进行授权,可以创建策略。关于如何创建策略,请参考document。例如

Startup.cs

    services.AddAuthorization(options =>
    {
        options.AddPolicy("CheckGroups", policy =>
            policy.Requirements.Add(new GroupsCheckRequirement("YourGroupID")));
    });
    services.AddScoped<IAuthorizationHandler, GroupsCheckHandler>();

GroupsCheckRequirement.cs:

    public class GroupsCheckRequirement : IAuthorizationRequirement
    {
        public string groups;

        public GroupsCheckRequirement(string groups)
        {
            this.groups = groups;
        }
    }

GroupsCheckHandler.cs:

    public class GroupsCheckHandler : AuthorizationHandler<GroupsCheckRequirement>
    {
        private readonly ITokenAcquisition tokenAcquisition;
        private readonly IMSGraphService graphService;

        public GroupsCheckHandler(ITokenAcquisition tokenAcquisition, IMSGraphService MSGraphService)
        {
            this.tokenAcquisition = tokenAcquisition;
            this.graphService = MSGraphService;
        }
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                  GroupsCheckRequirement requirement)
        {
            string accessToken = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new[] { Constants.ScopeUserRead, Constants.ScopeDirectoryReadAll });

            User me = await graphService.GetMeAsync(accessToken);

            IList<Group> groups = await graphService.GetMyMemberOfGroupsAsync(accessToken);

            var result = false;
            foreach (var group in groups)
            {
                if (requirement.groups.Equals(group.Id))
                {
                    result = true;
                }
            }

            if (result)
            {
                context.Succeed(requirement);
            }

        }


    }

然后使用策略:

[Authorize(Policy = "CheckGroups")] 

此外,您还可以通过ASP.NET Core中间件库来实现它。通过在RoleClaimTypeTokenValidationParameters属性中指定声明,asp.net中间件支持从声明填充的角色。由于groups声明包含的安全组的对象ID比实际名称要多,因此您将使用组ID而不是组名。有关更多详细信息,请参见sample

Startup.cs

// The following lines code instruct the asp.net core middleware to use the data in the "groups" claim in the Authorize attribute and User.IsInrole()
            // See https://docs.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.2 for more info.
            services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
            {
                // Use the groups claim for populating roles
                options.TokenValidationParameters.RoleClaimType = "groups";
            });

然后使用它

[Authorize(Roles = “Group-object-id")] // In controllers
// or
User.IsInRole("Group-object-id"); // In methods
© www.soinside.com 2019 - 2024. All rights reserved.