Ocelot 与 Azure Active Directory 身份验证 .Net Core 3.1 集成
Ocelot Integration with Azure Active Directory Authentication .Net Core 3.1
上下文: 我的公司正在迁移到 API 网关来管理我们网络中的所有服务。每项服务目前都使用 azure AD 进行身份验证。一切都是单一租户,只允许公司用户使用。
问题:我的理解正确吗?
问题: 当我调用 http:localhost:5000/authResource/get 时,我从 Ocelot 收到了 401 响应。跟踪错误后,我发现当 Ocelot 身份验证中间件尝试使用 AzureADJwtBearer 方案进行身份验证时,我返回 null。
我听从了与 Ocelot 和 azure ad 相关的问题的建议,但即使这样我也无法正常工作。 (主要来自这个答案:)
我想我可能误解了身份验证应该如何工作。我目前的理解是,我告诉 Ocelot 使用 AzureADJwtBearer 方案针对我的一个 API 进行身份验证。在我的配置中,我有特定 api 设置的信息(ClientId、TenantId 等)。
调用路由后,我希望 Ocelot 调用 Microsoft 以开始身份验证。在这一点上,我期望与 Apis 提供的流程相同,即我拨打电话并获得 Microsoft 登录页面,然后在我输入用户名和密码后将我重定向回应用程序。
我猜在将我重定向回 Ocelot 之后(这是我不清楚的部分),我希望 ocelot 存储 Microsoft 为我刚刚请求的特定资源发回的访问令牌。然后我希望 ocelot 将令牌附加到 Auth header,然后发送对我最初请求的资源的请求。
为了澄清这一点,我将包括我的启动文件代码和我的 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 请求中提供授权 header 时,我才能从中获得响应。
我通过我的 Ocelot 网关向 url http://localhost:5000/authResource/get 发出请求(我在 localhost:5000 上托管 Ocelot)。
Ocelot 发现它需要进行身份验证才能访问此资源,因此它使用 AzureADJwtBearer 方案发出请求。
我被重定向到 Microsoft 进行登录。完成后,我会被发送回 Ocelot 应用程序,并附带一个访问令牌。
Ocelot 接受了这个,创建了 Auth header,最后调用 http://localhost:5003/api/Controller/Get 和 returns 结果。
.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 网关将正确验证它。
上下文: 我的公司正在迁移到 API 网关来管理我们网络中的所有服务。每项服务目前都使用 azure AD 进行身份验证。一切都是单一租户,只允许公司用户使用。 问题:我的理解正确吗? 问题: 当我调用 http:localhost:5000/authResource/get 时,我从 Ocelot 收到了 401 响应。跟踪错误后,我发现当 Ocelot 身份验证中间件尝试使用 AzureADJwtBearer 方案进行身份验证时,我返回 null。
我听从了与 Ocelot 和 azure ad 相关的问题的建议,但即使这样我也无法正常工作。 (主要来自这个答案:
调用路由后,我希望 Ocelot 调用 Microsoft 以开始身份验证。在这一点上,我期望与 Apis 提供的流程相同,即我拨打电话并获得 Microsoft 登录页面,然后在我输入用户名和密码后将我重定向回应用程序。
我猜在将我重定向回 Ocelot 之后(这是我不清楚的部分),我希望 ocelot 存储 Microsoft 为我刚刚请求的特定资源发回的访问令牌。然后我希望 ocelot 将令牌附加到 Auth header,然后发送对我最初请求的资源的请求。
为了澄清这一点,我将包括我的启动文件代码和我的 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 请求中提供授权 header 时,我才能从中获得响应。 我通过我的 Ocelot 网关向 url http://localhost:5000/authResource/get 发出请求(我在 localhost:5000 上托管 Ocelot)。 Ocelot 发现它需要进行身份验证才能访问此资源,因此它使用 AzureADJwtBearer 方案发出请求。 我被重定向到 Microsoft 进行登录。完成后,我会被发送回 Ocelot 应用程序,并附带一个访问令牌。 Ocelot 接受了这个,创建了 Auth header,最后调用 http://localhost:5003/api/Controller/Get 和 returns 结果。
.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 网关将正确验证它。