如何使用Microsoft Graph API在.net核心应用程序中获取所有用于授权的组?

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

我正在从事.net核心项目。我正在尝试使用AD组实施授权。我的要求是,天蓝色广告中有很多组。如果当前用户属于azure广告中的任何可用组,那么我想授权这些用户访问.net核心应用程序中编写的api。我尝试如下。我在下面两个类中添加了

 public class IsMemberOfGroupHandler : AuthorizationHandler<IsMemberOfGroupRequirement>
    {
        protected override Task HandleRequirementAsync(
            AuthorizationHandlerContext context, IsMemberOfGroupRequirement requirement)
        {
            var groupClaim = context.User.Claims
                 .FirstOrDefault(claim => claim.Type == "groups" &&
                     claim.Value.Equals(requirement.GroupId, StringComparison.InvariantCultureIgnoreCase));

            if (groupClaim != null)
                context.Succeed(requirement);

            return Task.CompletedTask;
        }
    }

 public class IsMemberOfGroupRequirement : IAuthorizationRequirement
    {
        public readonly string GroupId;
        public readonly string GroupName;

        public IsMemberOfGroupRequirement(string groupName, string groupId)
        {
            GroupName = groupName;
            GroupId = groupId;
        }
    }

下面是我的入门班。

 services.AddAuthorization(options =>
            {
                var adGroupConfig = new List<AdGroupConfig>();
                _configuration.Bind("AdGroups", adGroupConfig);

                foreach (var adGroup in adGroupConfig)
                    options.AddPolicy(
                        adGroup.GroupName,
                        policy =>
                            policy.AddRequirements(new IsMemberOfGroupRequirement(adGroup.GroupName, adGroup.GroupId)));
            });

以上代码检查配置文件中可用的组。现在,我的要求是使用Microsoft图形API来获取所有可用的组。我找不到任何方法来处理此要求。有人可以帮我弄这个吗?任何帮助,将不胜感激。谢谢

asp.net-core .net-core azure-active-directory authorization microsoft-graph
2个回答
1
投票

您可以使用this graph api获取用户直接所属的所有组。

GET /me/memberOf

在.net-core中,您可以使用GraphServiceClient调用图形api。这是一个示例供您参考。

var graphClient = new GraphServiceClient(
                new DelegateAuthenticationProvider(
                    (requestMessage) =>
                    {
                        // Get back the access token.
                        var accessToken = "";

                        if (!String.IsNullOrEmpty(accessToken))
                        {
                            // Configure the HTTP bearer Authorization Header
                            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
                        }
                        else
                        {
                            throw new Exception("Invalid authorization context");
                        }

                        return (Task.FromResult(0));
                    }
                    ));
            var groups = graphClient.Me.MemberOf.Request().GetAsync().Result;

0
投票

[请先检查this code sample,它使用OpenID Connect登录用户并使用MSAL获取Microsoft Graph API令牌以退出组。

如果配置您的应用程序以通过编辑清单来接收团体声明:

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

已登录用户所属的安全组的对象ID在令牌的组声明中返回。

如果用户属于超过超出限制的组的更多成员(SAML令牌为150,JWT令牌为200,则Microsoft Identity Platform不会在令牌中发出组声明。相反,它在令牌中包含超额声明,该声明指示应用程序查询Graph API以检索用户的组成员身份。

{
  ...
  "_claim_names": {
    "groups": "src1"
    },
    {
   "_claim_sources": {
    "src1": {
        "endpoint":"[Graph Url to get this user's group membership from]"
        }
    }
  ...
}

所以您可以按照以下过程进行操作:

  1. 检查索赔_claim_names,其中一个值是组。这表示超量。

  2. 如果找到,请调用_claim_sources中指定的端点以获取用户组。

  3. 如果未找到,请查看用户组的组声明。

当然,您可以使用group claims直接调用Microsoft Graph API退出当前用户的组

https://docs.microsoft.com/en-us/graph/api/user-list-memberof?view=graph-rest-1.0&tabs=http

然后您可以根据该组进行授权。例如,如果使用策略:

services.AddAuthorization(options =>
{
    options.AddPolicy("GroupsCheck", 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 = "GroupsCheck")] 
© www.soinside.com 2019 - 2024. All rights reserved.