2

背景:我的公司正在迁移到 API 网关来管理我们网络中的所有服务。每个服务当前都使用 azure AD 进行身份验证。一切都是单租户,只允许公司用户。 问:我理解正确吗? 问题:当我调用 http:localhost:5000/authResource/get 时,我收到了来自 Ocelot 的 401 响应。跟踪错误后,我看到当 Ocelot 身份验证中间件尝试使用 AzureADJwtBearer 方案进行身份验证时,我返回 null。

我遵循了与 Ocelot 和 azure ad 相关的问题的建议,但即使遵循这些建议,我也无法进行任何工作。(主要来自这个答案:How setup Ocelot Api Gateway with Azure Active Directory)我想我可能误解了身份验证应该如何工作。我目前的理解是,我告诉 Ocelot 使用 AzureADJwtBearer 方案对我的一个 API 进行身份验证。在我的配置中,我有该特定 api 设置的信息(ClientId、TenantId 等)。

一旦我调用了路由,我希望 Ocelot 会调用 Microsoft 以开始身份验证。在这一点上,我期望与 API 提供的流程相同,即我拨打电话并获取 Microsoft 登录页面,然后在我输入用户名和密码后将我重定向回应用程序。

在将我重定向回 Ocelot 后,我​​猜(这是我模糊的部分),我希望 ocelot 存储 Microsoft 为我刚刚请求的特定资源发回的访问令牌。然后我希望 ocelot 将令牌附加到 Auth 标头,然后发送对我最初要求的资源的请求。

为了澄清这一点,我将包含我的启动文件和我的 ocelot.json 文件的代码。来自 Startup.cs

public void ConfigureServices(IServiceCollection services)
        {

            services.AddProtectedWebApi(Configuration)
                .AddProtectedApiCallsWebApis(Configuration)
                .AddInMemoryTokenCaches();
            services.AddOcelot(Configuration);
            services.AddControllers();
        }

同样来自 Startup.cs

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            app.UseOcelot().Wait();


            app.UseAuthentication();
        }

我的已验证资源的 ocelot.json 文件如下(出于安全原因更改了名称):

{
      "DownstreamPathTemplate": "/api/Controller/Get",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5003
        }
      ],
      "UpstreamPathTemplate": "/authResource/get",
      "UpstreamHttpMethod": [ "GET" ],

      "AuthenticationOptions": {
        "AuthenticationProviderKey": "AzureADJwtBearer",
        "AllowedScopes": []
      }
    }

为了巩固我对此的理解,我将通过一个示例,使用 ocelot 配置中显示的示例 api。

我希望访问资源http://localhost:5003/api/Controller/Get,这是一个受保护的 API,这意味着如果我在获取请求中提供授权标头,我只能从中获得响应。我通过我的 ocelot 网关向 url http://localhost:5000/authResource/get发出请求(我在 localhost:5000 上托管 Ocelot)。Ocelot 发现它需要进行身份验证才能访问此资源,因此它使用 AzureADJwtBearer 方案发出请求。我被重定向到微软登录。完成后,我会带着访问令牌返回到 Ocelot 应用程序。Ocelot 接受此操作,创建 Auth 标头,最后调用http://localhost:5003/api/Controller/Get并返回结果。

4

1 回答 1

1

.Net Core 3.1 的工作示例

我最终使用 Microsoft.Identity.Web 库(当前版本位于https://github.com/AzureAD/microsoft-identity-web/tree/master/src/Microsoft.Identity.Web)完成了这项工作

首先,我的 ocelot 配置文件(ocelot.json):

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/myapp/api/{everything}",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "apphost.com",
          "Port": 443
        }
      ],
      "UpstreamPathTemplate": "/api/{everything}",
      "UpstreamHttpMethod": [ "GET", "POST" ],

      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Bearer",
        "AllowedScopes": []
      }
    }
  ]
}

注意 AuthenticationProviderKey 的值为 Bearer。

我的 appsettings.json 文件包含我的天蓝色配置:

"AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "mydomain.com",
    "TenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  }

最后,我的 Startup.cs 文件包含类似这样的内容(为简洁起见)

public void ConfigureServices(IServiceCollection services)
        {
            services.AddProtectedWebApi(Configuration)
                .AddProtectedApiCallsWebApis(Configuration)
                .AddInMemoryTokenCaches();

            services.AddOcelot(Configuration);
            services.AddControllers();
        }

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                IdentityModelEventSource.ShowPII = true;
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            app.UseOcelot().Wait();

            app.UseAuthentication();
        }

完成所有设置后,我可以传入使用我的 azure 凭据生成的不记名令牌,并且 ocelot 网关将正确验证它。

于 2020-06-25T06:51:46.360 回答