@@ -62,16 +62,8 @@ public static async Task ProcessAnyGroupsOverage(TokenValidatedContext context,
6262 // Remove any existing 'groups' claim
6363 RemoveExistingGroupsClaims ( identity ) ;
6464
65- // Re-populate the `groups` claim with the complete list of groups fetched from MS Graph
66- foreach ( var group in usergroups )
67- {
68- // The following code adds group ids to the 'groups' claim. But depending upon your requirement and the format of the 'groups' claim selected in
69- // the app registration, you might want to add other attributes than id to the `groups` claim, examples being;
70-
71- // For instance if the required format is 'NetBIOSDomain\sAMAccountName' then the code is as commented below:
72- // identity.AddClaim(new Claim("groups", group.OnPremisesNetBiosName+"\\"+group.OnPremisesSamAccountName));
73- identity . AddClaim ( new Claim ( "groups" , group ) ) ;
74- }
65+ // And re-populate
66+ RepopulateGroupsClaim ( usergroups , identity ) ;
7567
7668 // Here we add the groups in a cache variable so that calls to Graph can be minimized to fetch all the groups for a user.
7769 // IMPORTANT: Group list is cached for 1 hr by default, and thus cached groups will miss any changes to a users group membership for this duration.
@@ -109,7 +101,7 @@ private static bool IsAccessToken(ClaimsIdentity identity)
109101 /// <param name="context">TokenValidatedContext</param>
110102 private static async Task < List < string > > ProcessUserGroupsForOverage ( TokenValidatedContext context , List < string > requiredGroupIds )
111103 {
112- var allgroups = new List < Group > ( ) ;
104+ var allgroups = new List < string > ( ) ;
113105
114106 try
115107 {
@@ -135,55 +127,42 @@ private static async Task<List<string>> ProcessUserGroupsForOverage(TokenValidat
135127 context . HttpContext . Items . Add ( Cached_Graph_Token_Key , context . SecurityToken as JwtSecurityToken ) ;
136128 }
137129
138- // MS Graph call to fetch the entire set of group membership..
139-
140- // The properties that we want to retrieve from MemberOf endpoint.
141- string select = "id,displayName,onPremisesNetBiosName,onPremisesDomainName,onPremisesSamAccountNameonPremisesSecurityIdentifier" ;
142-
143- IUserMemberOfCollectionWithReferencesPage memberPage = new UserMemberOfCollectionWithReferencesPage ( ) ;
144-
145130 try
146131 {
147132 // Request to get groups and directory roles that the user is a direct member of.
148- memberPage = await graphClient . Me . MemberOf . Request ( ) . Select ( select ) . GetAsync ( ) . ConfigureAwait ( false ) ;
149- }
150- catch ( Exception graphEx )
151- {
152- var exMsg = graphEx . InnerException != null ? graphEx . InnerException . Message : graphEx . Message ;
153- Debug . WriteLine ( "Call to Microsoft Graph failed: " + exMsg ) ;
154- }
133+ var memberPage = await graphClient . Me . CheckMemberGroups ( requiredGroupIds ) . Request ( ) . PostAsync ( ) . ConfigureAwait ( false ) ;
134+ allgroups = memberPage . ToList < string > ( ) ;
155135
156- if ( memberPage ? . Count > 0 )
157- {
158- // There is a limit to number of groups returned in a page, so the method below make further calls to Microsoft graph to get all the groups.
159- allgroups = ProcessIGraphServiceMemberOfCollectionPage ( memberPage , requiredGroupIds ) ;
136+ // There is a limit to number of groups returned in a page, so the method below make further calls to Microsoft graph to get all the groups.
137+ // allgroups = ProcessIGraphServiceMemberOfCollectionPage(memberPage, requiredGroupIds);
160138
161- if ( allgroups ? . Count > 0 )
162- {
163- var principal = context . Principal ;
164-
165- if ( principal != null )
139+ if ( allgroups ? . Count > 0 )
166140 {
167- var identity = principal . Identity as ClaimsIdentity ;
141+ var principal = context . Principal ;
168142
169- // Checks if token is for protected APIs i.e., if token is 'Access Token'.
170- if ( IsAccessToken ( identity ) )
143+ if ( principal != null )
171144 {
172- // Remove existing groups claims
173- RemoveExistingGroupsClaims ( identity ) ;
145+ var identity = principal . Identity as ClaimsIdentity ;
146+
147+ // Checks if token is for protected APIs i.e., if token is 'Access Token'.
148+ if ( IsAccessToken ( identity ) )
149+ {
150+ // Remove existing groups claims
151+ RemoveExistingGroupsClaims ( identity ) ;
174152
175- // And re-populate
176- RepopulateGroupsClaim ( allgroups , identity ) ;
153+ // And re-populate
154+ RepopulateGroupsClaim ( allgroups , identity ) ;
155+ }
177156 }
178- }
179157
180- // return the full list of security groups
181- return allgroups . Select ( x => x . Id ) . ToList ( ) ;
182- }
158+ // return the full list of security groups
159+ return allgroups ;
160+ }
183161 }
184- else
162+ catch ( Exception graphEx )
185163 {
186- throw new ArgumentNullException ( "SecurityToken" , "Group membership cannot be fetched if no token has been provided." ) ;
164+ var exMsg = graphEx . InnerException != null ? graphEx . InnerException . Message : graphEx . Message ;
165+ Debug . WriteLine ( "Call to Microsoft Graph failed: " + exMsg ) ;
187166 }
188167 }
189168 }
@@ -212,16 +191,16 @@ private static async Task<List<string>> ProcessUserGroupsForOverage(TokenValidat
212191 /// <param name="allgroups">The user's entire security group membership.</param>
213192 /// <param name="identity">The identity.</param>
214193 /// <autogeneratedoc />
215- private static void RepopulateGroupsClaim ( List < Group > allgroups , ClaimsIdentity identity )
194+ private static void RepopulateGroupsClaim ( List < string > allgroups , ClaimsIdentity identity )
216195 {
217- foreach ( Group group in allgroups )
196+ foreach ( string group in allgroups )
218197 {
219198 // The following code adds group ids to the 'groups' claim. But depending upon your requirement and the format of the 'groups' claim selected in
220199 // the app registration, you might want to add other attributes than id to the `groups` claim, examples being;
221200
222201 // For instance if the required format is 'NetBIOSDomain\sAMAccountName' then the code is as commented below:
223202 // identity.AddClaim(new Claim("groups", group.OnPremisesNetBiosName+"\\"+group.OnPremisesSamAccountName));
224- identity . AddClaim ( new Claim ( "groups" , group . Id ) ) ;
203+ identity . AddClaim ( new Claim ( "groups" , group ) ) ;
225204 }
226205 }
227206
@@ -294,52 +273,5 @@ private static void SaveUsersGroupsToCache(List<string> usersGroups, ClaimsPrinc
294273
295274 _memoryCache . Set ( cacheKey , usersGroups , cacheEntryOptions ) ;
296275 }
297-
298- /// <summary>
299- /// Paginates through the group membership page and fetches all subsequent pages to retrieve the entire list of a user's group membership
300- /// </summary>
301- /// <param name="membersCollectionPage">First page having collection of directory roles and groups</param>
302- /// <returns>List of groups</returns>
303- private static List < Group > ProcessIGraphServiceMemberOfCollectionPage ( IUserMemberOfCollectionWithReferencesPage membersCollectionPage , List < string > requiredGroupIds )
304- {
305- List < Group > allGroups = new List < Group > ( ) ;
306-
307- try
308- {
309- if ( membersCollectionPage != null )
310- {
311- do
312- {
313- // Page through results
314- foreach ( DirectoryObject directoryObject in membersCollectionPage . CurrentPage )
315- {
316- // Collection contains directory roles and groups of the user.
317- // Checks and adds groups only to the list.
318- if ( directoryObject is Group && requiredGroupIds . Contains ( directoryObject . Id ) )
319- {
320- allGroups . Add ( directoryObject as Group ) ;
321- }
322- }
323-
324- // Are there more pages (i.e has a @odata.nextLink) AND did we already found all the required groups
325- if ( membersCollectionPage . NextPageRequest != null && allGroups . Count ( ) != requiredGroupIds . Count ( ) )
326- {
327- membersCollectionPage = membersCollectionPage . NextPageRequest . GetAsync ( ) . Result ;
328- }
329- else
330- {
331- membersCollectionPage = null ;
332- }
333- } while ( membersCollectionPage != null ) ;
334- }
335- }
336- catch ( ServiceException ex )
337- {
338- Console . WriteLine ( $ "We could not process the groups page: { ex } ") ;
339- return null ;
340- }
341-
342- return allGroups ;
343- }
344276 }
345277}
0 commit comments