Skip to content

Commit 2b77f8e

Browse files
committed
Updates as per review comments
1 parent d0b8e37 commit 2b77f8e

File tree

4 files changed

+80
-66
lines changed

4 files changed

+80
-66
lines changed

5-WebApp-AuthZ/5-2-Groups/Infrastructure/CustomAuthorization.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
namespace WebApp_OpenIDConnect_DotNet.Infrastructure
1111
{
1212
/// <summary>
13-
/// GroupPolicyHandler represents Policy-based authorization.
13+
/// GroupPolicyHandler deals with custom Policy-based authorization.
1414
/// GroupPolicyHandler evaluates the GroupPolicyRequirement against AuthorizationHandlerContext
15-
/// to determine if authorization is allowed.
15+
/// by calling CheckUsersGroupMembership method to determine if authorization is allowed.
1616
/// </summary>
1717
public class GroupPolicyHandler : AuthorizationHandler<GroupPolicyRequirement>
1818
{

5-WebApp-AuthZ/5-2-Groups/README.md

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ The following files have the code that would be of interest to you:
331331
```
332332

333333
- have been replaced by these lines:
334-
334+
335335
```CSharp
336336
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
337337
.AddMicrosoftIdentityWebApp(
@@ -353,56 +353,68 @@ The following files have the code that would be of interest to you:
353353

354354
`AddMicrosoftGraph` registers the service for `GraphServiceClient`. The values for BaseUrl and Scopes defined in `GraphAPI` section of **appsettings.json**.
355355

356-
1. In GraphHelper.cs, ProcessClaimsForGroupsOverage method uses `GraphServiceClient` to retrieve groups for the signed-in user from [/me/memberOf](https://docs.microsoft.com/graph/api/user-list-memberof) endpoint. All the groups are stored in list of claims and the data can be used in the application as per requirement.
357-
358-
```csharp
359-
public static async Task ProcessClaimsForGroupsOverage(TokenValidatedContext context)
360-
{
361-
if (context.Principal.Claims.Any(x => x.Type == "hasgroups" || (x.Type == "_claim_names" && x.Value == "{\"groups\":\"src1\"}")))
362-
{
363-
var graphClient = context.HttpContext.RequestServices.GetService<GraphServiceClient>();
364-
if (graphClient == null)
365-
{
366-
Console.WriteLine("No service for type 'Microsoft.Graph.GraphServiceClient' has been registered.");
367-
}
368-
else if (context.SecurityToken != null)
369-
{
370-
if (!context.HttpContext.Items.ContainsKey("JwtSecurityTokenUsedToCallWebAPI"))
371-
{
372-
context.HttpContext.Items.Add("JwtSecurityTokenUsedToCallWebAPI", context.SecurityToken as JwtSecurityToken);
373-
}
374-
string select = "id,displayName,onPremisesNetBiosName,onPremisesDomainName,onPremisesSamAccountNameonPremisesSecurityIdentifier";
375-
IUserMemberOfCollectionWithReferencesPage memberPage = new UserMemberOfCollectionWithReferencesPage();
376-
try
377-
{
378-
memberPage = await graphClient.Me.MemberOf.Request().Select(select).GetAsync().ConfigureAwait(false);
379-
}
380-
catch(Exception graphEx)
381-
{
382-
var exMsg = graphEx.InnerException != null ? graphEx.InnerException.Message : graphEx.Message;
383-
Console.WriteLine("Call to Microsoft Graph failed: "+ exMsg);
384-
}
385-
if (memberPage?.Count > 0)
386-
{
387-
var allgroups = ProcessIGraphServiceMemberOfCollectionPage(memberPage);
388-
if (allgroups?.Count > 0)
389-
{
390-
var identity = (ClaimsIdentity)context.Principal.Identity;
391-
if (identity != null)
392-
{
393-
RemoveExistingClaims(identity);
394-
List<Claim> groupClaims = new List<Claim>();
395-
foreach (Group group in allgroups)
396-
{
397-
groupClaims.Add(new Claim("groups", group.Id));
398-
}
399-
}
400-
}
401-
}
402-
}
403-
}
404-
....
405-
}
356+
1. In GraphHelper.cs, ProcessClaimsForGroupsOverage method uses `GraphServiceClient` to retrieve groups for the signed-in user from [/me/memberOf](https://docs.microsoft.com/graph/api/user-list-memberof) endpoint. All the group ids are stored in list of claims and the data can be used in the application as per requirement.
357+
358+
```csharp
359+
public static async Task ProcessClaimsForGroupsOverage(TokenValidatedContext context)
360+
{
361+
if (context.Principal.Claims.Any(x => x.Type == "hasgroups" || (x.Type == "_claim_names" && x.Value == "{\"groups\":\"src1\"}")))
362+
{
363+
var graphClient = context.HttpContext.RequestServices.GetService<GraphServiceClient>();
364+
if (graphClient == null)
365+
{
366+
Console.WriteLine("No service for type 'Microsoft.Graph.GraphServiceClient' has been registered.");
367+
}
368+
else if (context.SecurityToken != null)
369+
{
370+
if (!context.HttpContext.Items.ContainsKey("JwtSecurityTokenUsedToCallWebAPI"))
371+
{
372+
context.HttpContext.Items.Add("JwtSecurityTokenUsedToCallWebAPI", context.SecurityToken as JwtSecurityToken);
373+
}
374+
string select = "id,displayName,onPremisesNetBiosName,onPremisesDomainName,onPremisesSamAccountNameonPremisesSecurityIdentifier";
375+
IUserMemberOfCollectionWithReferencesPage memberPage = new UserMemberOfCollectionWithReferencesPage();
376+
try
377+
{
378+
memberPage = await graphClient.Me.MemberOf.Request().Select(select).GetAsync().ConfigureAwait(false);
379+
}
380+
catch(Exception graphEx)
381+
{
382+
var exMsg = graphEx.InnerException != null ? graphEx.InnerException.Message : graphEx.Message;
383+
Console.WriteLine("Call to Microsoft Graph failed: "+ exMsg);
384+
}
385+
if (memberPage?.Count > 0)
386+
{
387+
var allgroups = ProcessIGraphServiceMemberOfCollectionPage(memberPage);
388+
if (allgroups?.Count > 0)
389+
{
390+
var identity = (ClaimsIdentity)context.Principal.Identity;
391+
if (identity != null)
392+
{
393+
RemoveExistingClaims(identity);
394+
List<Claim> groupClaims = new List<Claim>();
395+
foreach (Group group in allgroups)
396+
{
397+
groupClaims.Add(new Claim("groups", group.Id));
398+
}
399+
}
400+
}
401+
}
402+
}
403+
}
404+
....
405+
}
406+
```
407+
408+
If application is using different group property type for instance, `NetBIOSDomain\sAMAccountName` then replace
409+
410+
```csharp
411+
groupClaims.Add(new Claim("groups", group.Id));
412+
```
413+
414+
with
415+
416+
```csharp
417+
groupClaims.Add(group.OnPremisesNetBiosName+"\\"+group.OnPremisesSamAccountName));
406418
```
407419

408420
1. UserProfile\Index.cshtml

5-WebApp-AuthZ/5-2-Groups/Services/MicrosoftGraph-Rest/GraphHelper.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,19 @@ public static async Task<List<string>> GetSignedInUsersGroups(TokenValidatedCont
2525
{
2626
List<string> groupClaims = new List<string>();
2727

28-
// Gets group values from session variable if exists.
29-
groupClaims = GetSessionGroupList(context.HttpContext.Session);
30-
if (groupClaims?.Count>0)
31-
{
32-
return groupClaims;
33-
}
3428
// Checks if the incoming token contained a 'Group Overage' claim.
35-
else if (HasOverageOccurred(context.Principal))
29+
if (HasOverageOccurred(context.Principal))
3630
{
37-
groupClaims= await ProcessUserGroupsForOverage(context);
31+
// Gets group values from session variable if exists.
32+
groupClaims = GetSessionGroupList(context.HttpContext.Session);
33+
if (groupClaims?.Count > 0)
34+
{
35+
return groupClaims;
36+
}
37+
else
38+
{
39+
groupClaims = await ProcessUserGroupsForOverage(context);
40+
}
3841
}
3942
return groupClaims;
4043
}
@@ -72,12 +75,11 @@ private static bool HasOverageOccurred(ClaimsPrincipal identity)
7275
/// </summary>
7376
/// <param name="context"></param>
7477
/// <returns></returns>
75-
static async Task<List<string>> ProcessUserGroupsForOverage(TokenValidatedContext context)
78+
private static async Task<List<string>> ProcessUserGroupsForOverage(TokenValidatedContext context)
7679
{
7780
List<string> groupClaims = new List<string>();
7881
try
7982
{
80-
8183
// Before instatntiating GraphServiceClient, the app should have granted admin consent for 'GroupMember.Read.All' permission.
8284
var graphClient = context.HttpContext.RequestServices.GetService<GraphServiceClient>();
8385

@@ -226,7 +228,7 @@ public static bool CheckUsersGroupMembership(AuthorizationHandlerContext context
226228
{
227229
bool result = false;
228230
// Checks if groups claim exists in claims collection of signed-in User.
229-
if(HasOverageOccurred(context.User))
231+
if (HasOverageOccurred(context.User))
230232
{
231233
// Calls method GetSessionGroupList to get groups from session.
232234
var groups = GetSessionGroupList(_httpContextAccessor.HttpContext.Session);
@@ -239,7 +241,7 @@ public static bool CheckUsersGroupMembership(AuthorizationHandlerContext context
239241
}
240242
else if (context.User.Claims.Any(x => x.Type == "groups" && x.Value == GroupName))
241243
{
242-
result = true;
244+
result = true;
243245
}
244246
return result;
245247
}

5-WebApp-AuthZ/5-2-Groups/Startup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void ConfigureServices(IServiceCollection services)
4747
options.Events.OnTokenValidated = async context =>
4848
{
4949
//Calls method to process groups overage claim.
50-
var groupClaims = await GraphHelper.GetSignedInUsersGroups(context);
50+
var overageGroupClaims = await GraphHelper.GetSignedInUsersGroups(context);
5151
};
5252
}, options => { Configuration.Bind("AzureAd", options); })
5353
.EnableTokenAcquisitionToCallDownstreamApi(options => Configuration.Bind("AzureAd", options), initialScopes)

0 commit comments

Comments
 (0)