I am working on .net core project. I am trying to implement authorize using AD groups. My requirement is, I have many groups in the azure ad. If the current user belongs to
Please firstly check this code sample , which use OpenID Connect to sign in users and use MSAL to get the Microsoft Graph API token to retire groups .
If config the your application to receive group claims by editing the manifest :
{
...
"errorUrl": null,
"groupMembershipClaims": "SecurityGroup",
...
}
The object id of the security groups the signed in user is member of is returned in the groups claim of the 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]"
}
}
...
}
So you can follow the process :
Check for the claim _claim_names with one of the values being groups. This indicates overage.
If found, make a call to the endpoint specified in _claim_sources to fetch user’s groups.
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
:
https://docs.microsoft.com/en-us/graph/api/user-list-memberof?view=graph-rest-1.0&tabs=http
You can then authorize based on that groups . For example , if using policy :
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);
}
}
}
And then using policy :
[Authorize(Policy = "GroupsCheck")]
You can use this graph api to get all the groups the user is a direct member of.
GET /me/memberOf
In .net-core you can use GraphServiceClient to call graph api. Here is a sample for your reference.
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;