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

标签 asp.net-core .net-core azure-active-directory authorization microsoft-graph-api

我正在从事 .net 核心项目。我正在尝试使用 AD 组实现授权。我的要求是,我在天蓝色的广告中有很多组。如果当前用户属于 azure ad 中的任何可用组,那么我想授权这些用户访问以 .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 graph api 来获取所有可用的组。我找不到任何方法来处理这个要求。有人可以帮我弄这个吗?任何帮助,将不胜感激。谢谢

最佳答案

请先查看this code sample ,它使用 OpenID Connect 登录用户并使用 MSAL 获取 Microsoft Graph API token 以停用组。

如果通过编辑 list 将您的应用程序配置为接收组声明:

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

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

If a user is member of more groups than the overage limit (150 for SAML tokens, 200 for JWT tokens), then the Microsoft Identity Platform does not emit the groups claim in the token. 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.

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

所以你可以按照流程进行:

  1. Check for the claim _claim_names with one of the values being groups. This indicates overage.

  2. If found, make a call to the endpoint specified in _claim_sources to fetch user’s groups.

  3. If none found, look into the groups claim for user’s groups.

当然,您可以直接调用 Microsoft Graph API 来退出当前用户的群组无需使用group claim:

https://learn.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")] 

关于asp.net-core - 如何使用 Microsoft Graph API 获取 .net 核心应用程序中的所有授权组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58091323/

相关文章:

asp.net-core - Blazor 清理 MarkupString

c# - Azure B2C 身份验证(Angular + .net core Web API)- 不记名 token 中未找到范围或角色声明

sql-server - 是否可以从本地 SQL Server 查询 Azure Active Directory?

c# - 带有模式的 Switch 语句

c# - dotnet-test 可以指定运行时标识符吗?

asp.net-mvc - 如何在 MVC Controller 中获取不记名 token ?

c# - Azure Active Directory 跟踪作者和编辑者字段

asp.net-core - 用于点对点视频聊天的 ASP.NET Core 和 WebRTC

c# - ASP.NET Core MVC 本地化警告 : AcceptLanguageHeaderRequestCultureProvider returned the following unsupported cultures

rabbitmq - Masstransit 无法从 docker 容器访问主机 RabbitMQ