Ocelot与Azure Active Directory身份验证.Net Core 3.1集成

时间:2020-02-15 02:18:41

标签: azure-active-directory api-gateway asp.net-core-3.1 ocelot

上下文:我的公司正在迁移到API网关,以管理我们网络中的所有服务。当前,每个服务都使用Azure AD进行身份验证。一切都是单租户,只允许公司用户使用。 问题:我是否理解正确? 问题:当我致电http:localhost:5000 / authResource / get时,我从Ocelot收到了401响应。查错后,我发现Ocelot身份验证中间件尝试使用AzureADJwtBearer方案进行身份验证时,我得到的返回值为空。

我遵循了与Ocelot和azure广告有关的问题的建议,但即使如此,我也无济于事。 (主要来自此答案:How set up Ocelot Api Gateway with Azure Active Directory) 我想我可能会误解身份验证应该如何工作。我目前的理解是,我告诉Ocelot使用AzureADJwtBearer方案对我的Apis进行身份验证。在我的配置中,我具有该特定api设置的信息(ClientId,TenantId等)。

一旦我拨打了路由,我希望Ocelot会打电话给Microsoft以启动身份验证。此时,我期望与Apis提供的流程相同,即拨打电话并获得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,这意味着如果我在get请求中提供了授权标头,则只能从中获得响应。 我通过ocelot网关请求URL http://localhost:5000/authResource/get(我在本地主机:5000上托管Ocelot)。 Ocelot认为需要验证才能访问此资源,因此它使用AzureADJwtBearer方案发出请求。 我被重定向到Microsoft登录。完成后,我将带有一个访问令牌的邮件发送回Ocelot应用程序。 Ocelot接受此操作,创建Auth头,最后调用http://localhost:5003/api/Controller/Get并返回结果。

1 个答案:

答案 0 :(得分:0)

.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文件包含我的Azure配置:

"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网关会正确地对其进行验证。