简体   繁体   English

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

[英]How to do authorization based on groups in .net core app?

net core application.网络核心应用程序。 My requirement is to add group based authorization.我的要求是添加基于组的授权。 I am user in Azure AD.我是 Azure AD 的用户。 I belong to the some group names starts with BR and AR.我属于一些以 BR 和 AR 开头的组名。 Users belong to the AR groups only should be able to access my APIs.只有属于 AR 组的用户才能访问我的 API。 Currently my client application is Swagger and I am hitting APIS only through swagger.目前我的客户端应用程序是 Swagger,我只通过 swagger 访问 APIS。

For example, In startup I can have the below code.例如,在启动时我可以有下面的代码。

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

In controller,在 controller 中,

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

In the above approach, I am hard coding but I do not want to hard code.在上述方法中,我是硬编码,但我不想硬编码。 First of all I am not getting groups info in JWT token and I am getting首先,我没有在 JWT 令牌中获得组信息,我得到了

hasGroups:true in my JWT token. hasGroups:true 在我的 JWT 令牌中。 Instead of hard coding I want to get it from Graph API.我想从 Graph API 中获取它,而不是硬编码。 Can someone help me how to do this?有人可以帮我怎么做吗? I am not able to get any related example in internet.我无法在互联网上获得任何相关示例。 So can someone help me?那么有人可以帮助我吗?

If you want to config your application to receive group claims, you need to set the " groupMembershipClaims " value as SecurityGroup in the Manifest file.如果您想配置您的应用程序以接收组声明,您需要在 Manifest 文件中将“ groupMembershipClaims ”值设置为SecurityGroup

  1. In your application settings page on the Application Registration Portal, click on "Manifest" to open the inline manifest editor.在应用程序注册门户上的应用程序设置页面中,单击“清单”以打开内联清单编辑器。

  2. Edit the manifest by locating the "groupMembershipClaims" setting, and setting its value to "SecurityGroup".通过找到“groupMembershipClaims”设置并将其值设置为“SecurityGroup”来编辑清单。

  3. Save the manifest.保存清单。

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

When the groups claim is enabled for an application, Azure AD includes a claim in the JWT and SAML tokens that contains the object identifiers (objectId) of all the groups to which the user belongs, including transitive group membership.当为应用程序启用组声明时,Azure AD 在 JWT 和 SAML 令牌中包含一个声明,其中包含所有组的 object 标识符(objectId),包括用户所属的传递组成员身份。

But please note that to ensure that the token size doesn't exceed HTTP header size limits, Azure AD limits the number of objectIds that it includes in the groups claim.但请注意,为确保令牌大小不超过 HTTP header 大小限制,Azure AD 限制了它包含在组中声明的 objectId 的数量。 If a user is member of more groups than the overage limit (150 for SAML tokens, 200 for JWT tokens), then Azure AD does not emit the groups claim in the token.如果用户是超过超额限制的组的成员(SAML 令牌为 150 个,JWT 令牌为 200 个),则 Azure AD 不会在令牌中发出组声明。 Instead, it includes an overage claim in the token that indicates to the application to query the Graph API to retrieve the user's group membership.相反,它在令牌中包含一个超额声明,指示应用程序查询 Graph API 以检索用户的组成员身份。 For more details, please refer to the blog .更多详情,请参阅博客

在此处输入图像描述

So you need to do some process:所以你需要做一些过程:

  1. Check for the claim _claim_names with one of the values being groups.检查声明_claim_names,其中一个值为组。 This indicates overage.这表明超龄。

  2. If found, make a call to the endpoint specified in _claim_sources to fetch user's groups.如果找到,请调用 _claim_sources 中指定的端点以获取用户组。

  3. If none found, look into the groups claim for user's groups.如果没有找到,请查看用户组的组声明。

Of course, you can directly call Microsoft Graph API to retire current user's groups without using group claims当然,您可以直接调用Microsoft Graph API退出当前用户的群组,无需使用group claims

Regarding how to authorize based on that groups, you can create a policy.关于如何基于该组进行授权,您可以创建一个策略。 For more details, please refer to the document .更多详细信息,请参阅文档 For example例如

Startup.cs启动.cs

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

GroupsCheckRequirement.cs: GroupsCheckRequirement.cs:

    public class GroupsCheckRequirement : IAuthorizationRequirement
    {
        public string groups;

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

GroupsCheckHandler.cs: 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);
            }

        }


    }

And then using policy:然后使用策略:

[Authorize(Policy = "CheckGroups")] 

Besides, you also can implement it by ASP.NET Core middleware libraries.此外,您还可以通过 ASP.NET Core 中间件库来实现它。 The asp.net middleware supports roles populated from claims by specifying the claim in the RoleClaimType property of TokenValidationParameters . asp.net 中间件通过在TokenValidationParametersRoleClaimType属性中指定声明来支持从声明填充的角色。 Since the groups claim contains the object ids of the security groups than actual names, you'd use the group ids instead of group names.由于groups声明包含安全组的 object id 而不是实际名称,因此您将使用组 id 而不是组名。 For more details, please refer to the sample .有关详细信息,请参阅示例

Startup.cs启动.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";
            });

Then using it然后使用它

[Authorize(Roles = “Group-object-id")] // In controllers
// or
User.IsInRole("Group-object-id"); // In methods

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM