I want to retrieve all groups assigned to a logged in user when user signed in. So that the groups can be used for the user's logged-in session.
I followed the code from the link below,
and modified to call GetMyMemberOfGroupsAsync()
like below, but get exception shown at the bottom.
public void ConfigureServices(IServiceCollection services)
{
...
// Sign-in users with the Microsoft identity platform
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(
options =>
{
Configuration.Bind("AzureAd", options);
options.Events = new OpenIdConnectEvents();
options.Events.OnTokenValidated = async context =>
{
var graphService = sp.GetService<IGraphService>();
await graphService.GetMyMemberOfGroupsAsync();
};
}, options => { Configuration.Bind("AzureAd", options); })
.EnableTokenAcquisitionToCallDownstreamApi(options => Configuration.Bind("AzureAd", options), initialScopes)
.AddMicrosoftGraph(Configuration.GetSection("GraphAPI"))
.AddInMemoryTokenCaches();
...
}
Below is the code added to the code example to get all groups, but exception is thrown at the line of _graphServiceClient.Me.MemberOf.Request().GetAsync();
public class GraphService : IGraphService
{
private readonly GraphServiceClient _graphServiceClient;
public GraphService(GraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient;
}
public async Task<List<string>> GetMyMemberOfGroupsAsync()
{
List<string> groups = new List<string>();
// Get groups the current user is a direct member of.
IUserMemberOfCollectionWithReferencesPage memberOfGroups = await _graphServiceClient.Me.MemberOf.Request().GetAsync(); //exception thrown
if (memberOfGroups?.Count > 0)
{
foreach (var directoryObject in memberOfGroups)
{
// We only want groups, so ignore DirectoryRole objects.
if (directoryObject is Group)
{
Group group = directoryObject as Group;
groups.Add(group.DisplayName);
}
}
}
// If paginating
while (memberOfGroups.NextPageRequest != null)
{
memberOfGroups = await memberOfGroups.NextPageRequest.GetAsync();
if (memberOfGroups?.Count > 0)
{
foreach (var directoryObject in memberOfGroups)
{
// We only want groups, so ignore DirectoryRole objects.
if (directoryObject is Group)
{
Group group = directoryObject as Group;
groups.Add(group.DisplayName);
}
}
}
}
return groups;
}
}
Exception below is thrown at the line of _graphServiceClient.Me.MemberOf.Request().GetAsync();
System.Exception: An error was encountered while handling the remote login.
---> Status Code: 0
Microsoft.Graph.ServiceException: Code: generalException
Message: An error occurred sending the request.
---> Microsoft.Identity.Web.MicrosoftIdentityWebChallengeUserException: IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user. See https://aka.ms/ms-id-web/ca_incremental-consent.
---> MSAL.NetCore.4.18.0.0.MsalUiRequiredException:
ErrorCode: user_null
Microsoft.Identity.Client.MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call.
at Microsoft.Identity.Client.AcquireTokenSilentParameterBuilder.Validate()
at Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder`1.ValidateAndCalculateApiId()
at Microsoft.Identity.Client.AbstractClientAppBaseAcquireTokenParameterBuilder`1.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder`1.ExecuteAsync()
at Microsoft.Identity.Web.TokenAcquisition.GetAuthenticationResultForWebAppWithAccountFromCacheAsync(IConfidentialClientApplication application, IAccount account, IEnumerable`1 scopes, String authority, String userFlow)
at Microsoft.Identity.Web.TokenAcquisition.GetAuthenticationResultForWebAppWithAccountFromCacheAsync(IConfidentialClientApplication application, ClaimsPrincipal claimsPrincipal, IEnumerable`1 scopes, String authority, String userFlow)
at Microsoft.Identity.Web.TokenAcquisition.GetAuthenticationResultForUserAsync(IEnumerable`1 scopes, String tenant, String userFlow, ClaimsPrincipal user)
StatusCode: 0
ResponseBody:
Headers:
--- End of inner exception stack trace ---
at Microsoft.Identity.Web.TokenAcquisition.GetAuthenticationResultForUserAsync(IEnumerable`1 scopes, String tenant, String userFlow, ClaimsPrincipal user)
at Microsoft.Identity.Web.TokenAcquisition.GetAccessTokenForUserAsync(IEnumerable`1 scopes, String tenant, String userFlow, ClaimsPrincipal user)
at Microsoft.Identity.Web.TokenAcquisitionCredentialProvider.AuthenticateRequestAsync(HttpRequestMessage request)
at Microsoft.Graph.AuthenticationHandler.SendAsync(HttpRequestMessage httpRequestMessage, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Microsoft.Graph.HttpProvider.SendRequestAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at Microsoft.Graph.HttpProvider.SendRequestAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at Microsoft.Graph.HttpProvider.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at Microsoft.Graph.BaseRequest.SendRequestAsync(Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.BaseRequest.SendAsync[T](Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.UserMemberOfCollectionWithReferencesRequest.GetAsync(CancellationToken cancellationToken)
at WebApp_OpenIDConnect_DotNet.Controllers.GraphService.GetMyMemberOfGroupsAsync() in C:\_MyLab\AzureCode\ActiveDirectory\active-directory-aspnetcore-webapp-openidconnect-v2-v2\5-WebApp-AuthZ\5-2-Groups\Controllers\GraphService.cs:line 20
at WebApp_OpenIDConnect_DotNet.Startup.<>c__DisplayClass4_0.<<ConfigureServices>b__8>d.MoveNext() in C:\_MyLab\AzureCode\ActiveDirectory\active-directory-aspnetcore-webapp-openidconnect-v2-v2\5-WebApp-AuthZ\5-2-Groups\Startup.cs:line 62
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>c__DisplayClass10_1.<<WebAppCallsWebApiImplementation>b__2>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.RunTokenValidatedEventAsync(OpenIdConnectMessage authorizationResponse, OpenIdConnectMessage tokenEndpointResponse, ClaimsPrincipal user, AuthenticationProperties properties, JwtSecurityToken jwt, String nonce)
at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleRemoteAuthenticateAsync()
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
If your app requests more scopes than what the admin has consented, you'll receive an
MsalUiRequiredException
, so make sure that you have granted sufficient permissions to your application and granted admin consent to that permission.If you need to retrieve all the groups assigned to the logged-in user when the user logs in, please refer to the following code: