我正在从事.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来获取所有可用的组。我找不到任何方法来处理此要求。有人可以帮我弄这个吗?任何帮助,将不胜感激。谢谢
您可以使用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;
[请先检查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]"
}
}
...
}
所以您可以按照以下过程进行操作:
检查索赔_claim_names,其中一个值是组。这表示超量。
如果找到,请调用_claim_sources中指定的端点以获取用户组。
如果未找到,请查看用户组的组声明。
当然,您可以使用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")]