上下文:我的公司正在迁移到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并返回结果。
答案 0 :(得分:0)
我最终使用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网关会正确地对其进行验证。