从 ASP.NET Grpc 服务调用 Microsoft Graph 时出现问题
Problem calling Microsoft Graph from ASP.NET Grpc service
我有两个申请-
- public 客户端应用程序(.NET Core 控制台应用程序),用户在其中获取 Microsoft 身份访问令牌
- web API,它尝试使用该访问令牌
代表用户调用 Microsoft Graph
当我从 Web API 调用 Microsoft Graph 时,我收到 MicrosoftIdentityWebChallengeUserException,其内部异常状态为:
“用户或管理员未同意使用 ID <...> 名为 <...> 的应用程序。为此用户和资源发送交互式授权请求。”
我试过:
- 到 pre-authorize 服务应用程序中的客户端应用程序使用 Expose an API tab in Azure Portal
- 在 Manifest 选项卡的 knownClientApplications 数组中添加客户端应用程序 ID
- 在用户获得的访问令牌中包含 Microsoft Graph 所需的范围(例如“User.Read”)
但这似乎不起作用,我仍然得到同样的异常。
问题是 - 在调用 GRPC 服务之前,我能否通过在用户访问令牌中获取所有需要的权限来以某种方式避免这种异常情况,或者如果不能,那该怎么做我需要处理此异常以将其传播回用户。
完整详情here。继续执行后续步骤。
基本上,您需要:
在您的 API 项目中包含 Microsoft.Identity.Web 和 Microsoft.Identity.Web.MicrosoftGraph NuGet 包。
在 Azure 应用程序注册中设置客户端密码或证书。将其包含在您的 appsettings.json 文件中:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "{YOUR-DOMAIN-NAME-FROM-APP-REGISTRATION}",
"TenantId": "{YOUR-TENANT-ID-FROM-APP-REGISTRATION}",
"ClientId": "{YOUR-CLIENT-ID-FROM-APP-REGISTRATION}",
"Scopes": "{YOUR-API-ACCESS-SCOPE-FROM-APP-REGISTRATION}",
"CallbackPath": "/signin-oidc",
"ClientSecret": "{YOUR-CLIENT-SECRET-FROM-APP-REGISTRATION}"
}
在您的 appsettings.json 文件中包含以下部分:
"Graph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "User.Read"
}
在您的 Project.cs 文件或 Startup.cs 文件中包含以下代码(取决于您使用的 .Net 版本):
Startup.cs:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration, Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(Configuration.GetSection("Graph"))
.AddInMemoryTokenCaches();
Project.cs:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(builder.Configuration.GetSection("Graph"))
.AddInMemoryTokenCaches();
从那里,您只需将 GraphServiceClient 注入您的控制器或页面构造函数。上面的 link 提供了在 ASP.NET API 中实现的代码。我在 Blazor Webassembly 托管应用程序中使用此方法,因此我的实现需求与说明略有不同,但它应该是 running/working。
我有两个申请-
- public 客户端应用程序(.NET Core 控制台应用程序),用户在其中获取 Microsoft 身份访问令牌
- web API,它尝试使用该访问令牌 代表用户调用 Microsoft Graph
当我从 Web API 调用 Microsoft Graph 时,我收到 MicrosoftIdentityWebChallengeUserException,其内部异常状态为: “用户或管理员未同意使用 ID <...> 名为 <...> 的应用程序。为此用户和资源发送交互式授权请求。”
我试过:
- 到 pre-authorize 服务应用程序中的客户端应用程序使用 Expose an API tab in Azure Portal
- 在 Manifest 选项卡的 knownClientApplications 数组中添加客户端应用程序 ID
- 在用户获得的访问令牌中包含 Microsoft Graph 所需的范围(例如“User.Read”)
但这似乎不起作用,我仍然得到同样的异常。
问题是 - 在调用 GRPC 服务之前,我能否通过在用户访问令牌中获取所有需要的权限来以某种方式避免这种异常情况,或者如果不能,那该怎么做我需要处理此异常以将其传播回用户。
完整详情here。继续执行后续步骤。
基本上,您需要:
在您的 API 项目中包含 Microsoft.Identity.Web 和 Microsoft.Identity.Web.MicrosoftGraph NuGet 包。
在 Azure 应用程序注册中设置客户端密码或证书。将其包含在您的 appsettings.json 文件中:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "{YOUR-DOMAIN-NAME-FROM-APP-REGISTRATION}",
"TenantId": "{YOUR-TENANT-ID-FROM-APP-REGISTRATION}",
"ClientId": "{YOUR-CLIENT-ID-FROM-APP-REGISTRATION}",
"Scopes": "{YOUR-API-ACCESS-SCOPE-FROM-APP-REGISTRATION}",
"CallbackPath": "/signin-oidc",
"ClientSecret": "{YOUR-CLIENT-SECRET-FROM-APP-REGISTRATION}"
}
在您的 appsettings.json 文件中包含以下部分:
"Graph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "User.Read"
}
在您的 Project.cs 文件或 Startup.cs 文件中包含以下代码(取决于您使用的 .Net 版本):
Startup.cs:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration, Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(Configuration.GetSection("Graph"))
.AddInMemoryTokenCaches();
Project.cs:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(builder.Configuration.GetSection("Graph"))
.AddInMemoryTokenCaches();
从那里,您只需将 GraphServiceClient 注入您的控制器或页面构造函数。上面的 link 提供了在 ASP.NET API 中实现的代码。我在 Blazor Webassembly 托管应用程序中使用此方法,因此我的实现需求与说明略有不同,但它应该是 running/working。