简体   繁体   English

无法使用来自 Asp.Net 的代表流调用 graphAPI Web API

[英]Unable to call graphAPI using On-behalf-of flow from Asp.Net Web API

I'm trying to implement On-behalf-of user in Asp.net Web API (.net 5).我正在尝试在 Asp.net Web API (.net 5)中实现代表用户。 I receive an access_token from the Mobile APP, send it to my Web API.我从手机APP收到一个access_token,发送到我的Web API。 The Web API uses this token to call the GRAPH API to get the user's profile details. Web API 使用此令牌调用 GRAPH API 以获取用户的配置文件详细信息。 Below is my code Startup.cs file下面是我的代码 Startup.cs 文件

 services.AddAuthentication("JwtBearer")
                        .AddJwtBearer("JwtBearer", options =>
                        {
                            options.MetadataAddress = $"https://login.microsoftonline.com/{Configuration["b2bAzureAppIdentity:TenantId"]}/v2.0/.well-known/openid-configuration";
                            options.TokenValidationParameters = new TokenValidationParameters()
                            {
                                ValidIssuer = $"https://sts.windows.net/{Configuration["b2bAzureAppIdentity:TenantId"]}/",

                                // as audience, both the client id and the identifierUri are allowed (sematically equivalent)
                                ValidAudiences = new[] { Configuration["b2bAzureAppIdentity:AppIdUri"], Configuration["b2bAzureAppIdentity:ClientId"] }
                            };
                        }).AddMicrosoftIdentityWebApi(Configuration, "b2bAzureAppIdentity")
                        .EnableTokenAcquisitionToCallDownstreamApi()
                        .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
                        .AddInMemoryTokenCaches();

controller.cs controller.cs

 [HttpGet("GetMyDetails")]
    [AuthorizeForScopes(Scopes = new string[] { "user.read" })]
    public async Task<IActionResult> GetMyDetails()
    {
        var user = await _graphServiceClient.Me.Request().GetAsync();
        return new OkObjectResult(user.Photo);
    }

Appsettings is in the below format Appsettings 采用以下格式

 "b2bAzureAppIdentity": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "",
"TenantId": "",
"ClientId": "",
"ClientSecret": "",
"AppIdUri": ""},
 "DownstreamApi": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "user.read"},

In Azure, the API permissions and scope are set correctly, this is evident because when I make calls from postman, I'm able to get the accesstoken for on_behalf_of and use it to get the user's profile details by calling https://graph.microsoft.com/v1.0/me In Azure, the API permissions and scope are set correctly, this is evident because when I make calls from postman, I'm able to get the accesstoken for on_behalf_of and use it to get the user's profile details by calling https://graph. microsoft.com/v1.0/me

In the controller at this line在 controller 这一行

var user = await _graphServiceClient.Me.Request().GetAsync();

I get an error: "No account or login hint was passed to the AcquireTokenSilent call. "我收到一条错误消息:“没有向 AcquireTokenSilent 调用传递任何帐户或登录提示。”

I have googled for this error and the solution says that the user should consent the scope however it has already been consented by the admin in Azure portal.我已经用谷歌搜索了这个错误,解决方案说用户应该同意 scope 但是它已经得到了 Azure 门户中的管理员的同意。 Also, the fact that this is working in Postman makes be believe that the configurations for the APP and the API are correct.此外,这在 Postman 中工作的事实让人相信 APP 和 API 的配置是正确的。 在此处输入图像描述

Has anyone faced similar issue?有没有人遇到过类似的问题?

This is happening because the access_token received is not sent along with the request to get the user detail.发生这种情况是因为收到的 access_token 没有与获取用户详细信息的请求一起发送。 Here's an example of how to implement on behalf of provider :以下是如何代表提供者实施的示例:

// Create a client application.
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                .Create(clientId)
                .WithTenantId(tenantID)
                // The Authority is a required parameter when your application is configured 
                // to accept authentications only from the tenant where it is registered.
                .WithAuthority(authority)
                .WithClientSecret(clientSecret)
                .Build();
                
// Use the API reference to determine which scopes are appropriate for your API request.
// e.g. - https://docs.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http
var scopes = new string[] { "User.Read" };
// Create an authentication provider.
ClientCredentialProvider authenticationProvider = new OnBehalfOfProvider(confidentialClientApplication, scopes);

var jsonWebToken = actionContext.Request.Headers.Authorization.Parameter;
var userAssertion = new UserAssertion(jsonWebToken);
// Configure GraphServiceClient with provider.
GraphServiceClient graphServiceClient = new GraphServiceClient(authenticationProvider);
// Make a request
var me = await graphServiceClient.Me.Request().WithUserAssertion(userAssertion).GetAsync();

In this case the token is added to the request in the call to WithUserAssertion .在这种情况下,令牌会在对WithUserAssertion的调用中添加到请求中。

Please let me know if this helps, and if you have further questions.请让我知道这是否有帮助,如果您还有其他问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM