active-directory-aspnetcore-webapp-openidconnect-v2 icon indicating copy to clipboard operation
active-directory-aspnetcore-webapp-openidconnect-v2 copied to clipboard

Exception getting Azure AD groups via MS Graph with ASP.NET Core

Open PingPongSet opened this issue 5 years ago • 0 comments

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,

https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/5-WebApp-AuthZ/5-2-Groups

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)

Please provide us with the following information:

This issue is for a: (mark with an x)

- [x ] bug report -> please search issues before submitting
- [ ] feature request
- [ ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)

The issue was found for the following scenario:

Please add an 'x' for the scenario(s) where you found an issue

  1. Web app that signs in users
    1. [ ] with a work and school account in your organization: 1-WebApp-OIDC/1-1-MyOrg
    2. [ ] with any work and school account: /1-WebApp-OIDC/1-2-AnyOrg
    3. [ ] with any work or school account or Microsoft personal account: 1-WebApp-OIDC/1-3-AnyOrgOrPersonal
    4. [ ] with users in National or sovereign clouds 1-WebApp-OIDC/1-4-Sovereign
    5. [ ] with B2C users 1-WebApp-OIDC/1-5-B2C
  2. Web app that calls Microsoft Graph
    1. [ ] Calling graph with the Microsoft Graph SDK: 2-WebApp-graph-user/2-1-Call-MSGraph
    2. [ ] With specific token caches: 2-WebApp-graph-user/2-2-TokenCache
    3. [ ] Calling Microsoft Graph in national clouds: 2-WebApp-graph-user/2-4-Sovereign-Call-MSGraph
  3. [ ] Web app calling several APIs 3-WebApp-multi-APIs
  4. [ ] Web app calling your own Web API
    1. [ ] with a work and school account in your organization: 4-WebApp-your-API/4-1-MyOrg
    2. [ ] with B2C users: 4-WebApp-your-API/4-2-B2C
    3. [ ] with any work and school account: 4-WebApp-your-API/4-3-AnyOrg
  5. Web app restricting users
    1. [ ] by Roles: 5-WebApp-AuthZ/5-1-Roles
    2. [x ] by Groups: 5-WebApp-AuthZ/5-2-Groups
  6. [ ] Deployment to Azure
  7. [ ] Other (please describe)

Repro-ing the issue

Repro steps

Expected behavior

Actual behavior

Possible Solution

Additional context/ Error codes / Screenshots

Any log messages given by the failure

Add any other context about the problem here, such as logs.

OS and Version?

Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)

Versions

of ASP.NET Core, of MSAL.NET

Attempting to troubleshooting yourself:

Mention any other details that might be useful


Thanks! We'll be in touch soon.

PingPongSet avatar Sep 28 '20 17:09 PingPongSet