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



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

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

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

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

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

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

也来自启动.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": []
}
}

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

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

.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 凭据生成的持有者令牌,豹猫网关将正确验证它。

最新更新