简体   繁体   English

Azure AD:从其他 .net Core Web API 调用 .net Core Web API

[英]Azure AD: Call .net Core Web API from other .net Core Web API

I have a situation where there is a .net Core Web API that we use to manage some "machines".我有一种情况,我们使用 .net Core Web API 来管理一些“机器”。 One of the exposed API is a simulation of the operation of such machines.公开的 API 之一是模拟此类机器的操作。 The machines have different versions, each different versions have a different internal behavior but same interface.机器有不同的版本,每个不同的版本有不同的内部行为但相同的界面。

We have, then, developed a series of different .net Core Web API to simulate each different versions of the machines.然后,我们开发了一系列不同的 .net Core Web API 来模拟每个不同版本的机器。

I need therefore to call an API from an API, it's sound pretty straightforward as I'm doing it already with Microsoft Graph .因此,我需要从 API 调用 API,这听起来很简单,因为我已经在使用Microsoft Graph这样做了。

In startup.cs, I have:在startup.cs中,我有:

public void ConfigureServices(IServiceCollection services)
{
    // To protect the API with Azure AD
    services
        .AddProtectedWebApi(Configuration);

    // To have ITokenAcquisition when calling the specific simulation API
    services
        .AddMicrosoftIdentityPlatformAuthentication(Configuration)
        .AddMsal(Configuration, new string[] { Configuration["SimulationAPIv411:Scope"] })
        .AddInMemoryTokenCaches();

I'm testing it with Postman with this flow in mind:我正在用 Postman 测试它,并考虑到这个流程:

  1. I get a bearer token with Postman to access the generic API我通过 Postman 获得了一个不记名令牌以访问通用 API
  2. Postman call the SimulationDispatcherController in the generic API Postman 在通用 API 中调用 SimulationDispatcherController
  3. The SimulationDispatcherController calls the specific simulation API SimulationDispatcherController 调用特定的模拟 API
  4. The result flow back to Postman结果流回邮递员

What I'm experiencing is:我正在经历的是:

  1. If I leave it like this, in postman I get as result a login page如果我这样离开它,在邮递员中,我会得到一个登录页面

    <!-- Copyright (C) Microsoft Corporation. All rights reserved. --> <!DOCTYPE html> <html dir="ltr" class="" lang="en"> <head> <title>Sign in to your account</title> [...]
  2. If I remove the line .AddMicrosoftIdentityPlatformAuthentication(Configuration) then I can reach the SimulationDispatcherController but when it tries to call the other API I get the error:如果我删除.AddMicrosoftIdentityPlatformAuthentication(Configuration)那么我可以访问 SimulationDispatcherController 但是当它尝试调用其他 API 时,我收到错误消息:

     MSAL.NetCore.4.8.1.0.MsalUiRequiredException: ErrorCode: user_null Microsoft.Identity.Client.MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call. [...]

    I try to get the token with the ITokenAcquisition object, calling GetAccessTokenOnBehalfOfUserAsync(_Scopes);我尝试使用ITokenAcquisition对象获取令牌,调用GetAccessTokenOnBehalfOfUserAsync(_Scopes); where the scope is the required one for the specific API.其中范围是特定 API 所需的范围。

Do you have any suggestion or link to documentation that explain better how to configure the MSAL in an API that is protected by Azure AD?您是否有任何建议或指向文档的链接,以更好地解释如何在受 Azure AD 保护的 API 中配置 MSAL?

EDIT: As suggested in the answer, the only change required was:编辑:正如答案中所建议的,唯一需要的更改是:

.AddMsal(Configuration, new string[] { Configuration["SimulationAPIv411:Scope"] })

to

.AddProtectedApiCallsWebApis(Configuration)

That seems other specific simulation APIs are also protected by Azure AD , you can use OAuth 2.0 On-Behalf-Of flow which works in scenario where an application invokes a service/web API, which in turn needs to call another service/web API.似乎其他特定的模拟 API 也受 Azure AD 保护,您可以使用OAuth 2.0 On-Behalf-Of 流,该流程适用于应用程序调用服务/Web API 的场景,而后者又需要调用另一个服务/Web API。

Here is code sample for using OBO flow in asp.net core web api with MSAL 2.3 and later. 是在带有 MSAL 2.3 及更高版本的 asp.net core web api 中使用 OBO 流的代码示例。

If you want to call .net Core Web API from other .net Core Web API projected by Azure AD, you use the OAuth 2.0 On-Behalf-Of flow .如果要从 Azure AD 投射的其他 .net Core Web API 调用 .net Core Web API,请使用OAuth 2.0 On-Behalf-Of 流 The detailed steps are as below详细步骤如下

  1. Sign-in the user in the client application在客户端应用程序中登录用户
  2. Acquire a token to the Web API A and call it.获取 Web API A 的令牌并调用它。
  3. The Web API then calls another downstream Web API B (I use Microsoft Graph for test).然后 Web API 调用另一个下游 Web API B(我使用 Microsoft Graph 进行测试)。

Regarding how to configure it, please refer to the following steps:关于如何配置,请参考以下步骤:

Register the web api app注册 web api 应用程序

  1. Register APP 注册APP
  2. Create Client secrets创建客户端机密
  3. Configure permissions to access another web api . 配置访问另一个 web api 的权限 (I use Microsoft graph for test) (我使用微软图表进行测试)
  4. Configure an application to expose web APIs (Add scope for the api) 配置应用程序以公开 Web API (为 api 添加范围)

Register the client app注册客户端应用程序

  1. Register APP 注册APP
  2. Create Client secrets创建客户端机密
  3. Configure permissions to access web API 配置访问 Web API 的权限

Configure known client applications for web API application为 Web API 应用程序配置已知的客户端应用程序

  1. In the Azure portal, navigate to your Web api app registration and click on the Manifest section.在 Azure 门户中,导航到您的 Web api 应用注册并单击清单部分。

  2. Find the property knownClientApplications and add the Client IDs of the client applications找到属性 knownClientApplications 并添加客户端应用程序的客户端 ID

Configure project配置项目

  1. Add the reference Microsoft.Identity.Web to your project将引用Microsoft.Identity.Web添加到您的项目

  2. add the following code in appsettings.json在 appsettings.json 中添加以下代码

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "<your tenant id>",
    "ClientId": "<app id of Web API A>",
    "ClientSecret": "<app secret of Web API A>"
  },
  1. add the following code in stratup.cs在stratup.cs中添加以下代码
public void ConfigureServices(IServiceCollection services)
{
services.AddProtectedWebApi(Configuration)
                   .AddProtectedApiCallsWebApis(Configuration)
                   .AddInMemoryTokenCaches();
  1. Controller控制器
[Authorize]
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
              private readonly ITokenAcquisition _tokenAcquisition;
        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger, ITokenAcquisition tokenAcquisition)
        {
            _logger = logger;
            _tokenAcquisition = tokenAcquisition;
        }



        [HttpGet]
        public async Task<string> Get()
        {

            string[] scopes = { "user.read" }; // the scope of Web API B
            string accessToken = await _tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes);
            // you use the accessToken to call the Web API B
            GraphServiceClient client = new GraphServiceClient(new DelegateAuthenticationProvider(
                    async (requestMessage) =>
                    {
                        requestMessage.Headers.Authorization =
                            new AuthenticationHeaderValue("Bearer", accessToken);
                    }));

            User user =await client.Me.Request().GetAsync();
            return user.UserPrincipalName;
        }

     }

Test in the Postman在邮递员中测试

  1. Get Tthe access token for the Web API A获取 Web API A 的访问令牌在此处输入图片说明 在此处输入图片说明

  2. Call the Web API A then let Web API A call the Microsoft graph调用 Web API A 然后让 Web API A 调用 Microsoft 图在此处输入图片说明

For more details, please refer to the document and the sample更多详细信息,请参阅文档示例

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

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