问题描述
我要在用户登录时检索分配给登录用户的所有组。以便这些组可用于用户的登录会话。
,并进行了如下修改,以调用GetMyMemberOfGroupsAsync()
,但底部显示异常。
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();
...
}
下面是添加到代码示例中以获取所有组的代码,但是在_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;
}
}
下面的异常抛出到_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,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,ClaimsPrincipal user)
at Microsoft.Identity.Web.TokenAcquisition.GetAccesstokenForUserAsync(IEnumerable`1 scopes,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,CancellationToken cancellationToken)
at Microsoft.Graph.HttpProvider.SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
at Microsoft.Graph.BaseRequest.SendRequestAsync(Object serializableObject,CancellationToken cancellationToken,HttpCompletionoption completionoption)
at Microsoft.Graph.BaseRequest.SendAsync[T](Object serializableObject,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)
解决方法
如果您的应用请求的范围超出了管理员同意的范围,则会收到MsalUiRequiredException
,因此请确保已为您的应用授予足够的permissions并获得了管理员同意。
如果在用户登录时需要检索分配给已登录用户的所有组,请参考以下代码:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var securityEnabledOnly = true;
await graphClient.Me
.GetMemberGroups(securityEnabledOnly)
.Request()
.PostAsync();