如何使用 Ocelot 在 .Net Core API 网关中实现 Windows 身份验证,以便所有下游服务都可以访问 IWindowsPrincipal?

Posted

技术标签:

【中文标题】如何使用 Ocelot 在 .Net Core API 网关中实现 Windows 身份验证,以便所有下游服务都可以访问 IWindowsPrincipal?【英文标题】:How to implement Windows Authentication in a .Net Core API Gateway using Ocelot so that all downstream services can access IWindowsPrincipal? 【发布时间】:2021-12-30 20:17:03 【问题描述】:

背景

我有两个微服务需要访问调用用户的 IWindowsPrincipal。 我正在使用 .Net Core 3.1 编写一个 API 网关,它将充当这些服务的反向代理。 我在 API Gateway 中配置了 Authentication 和 Authorization 如下:

public void ConfigureServices(IServiceCollection services)

    services.AddCors(options =>
    
        options.AddPolicy("All allowed",
            builder =>
            
                builder
                    .AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
            );
    );

    services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
        .AddNegotiate();
    services.AddAuthorization();

    services.AddControllers();
    services.AddHttpForwarder();
    services.AddOcelot();
    services.AddSwaggerForOcelot(_configuration);


public void Configure(IApplicationBuilder app)

    app.UseCors("All allowed");

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

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

    app.UseSwaggerForOcelotUI(options =>
    
        options.PathToSwaggerGenerator = "/swagger/docs";
    );

    app.UseOcelot();

要求

我想使用 HttpContext.User.Identity 访问调用用户的身份 在微服务的方法中。

实际结果

在微服务的方法中,HttpContext.User.Identity.IsAuthenticated为false,身份信息为空。

问题

有没有办法在网关中配置 Ocelot,以便在必要时挑战调用者接收 Windows 身份验证信息并将其传递给微服务? 如果这不可能,是实现我的目标的推荐方法,在每个微服务中执行 Windows 身份验证? Ocelot 不应该允许我在一个地方为所有微服务处理身份验证吗?

按照问题 1

Ocelot 的文档是指使用 JWT 进行身份验证。 我是否应该断定 Ocelot 只提供 JWT 配置?

继续问题 2

我读过一些关于 Yarp 的文章 (https://microsoft.github.io/reverse-proxy/) 我应该使用 Yarp 而不是 Ocelot 来实现我的目标吗?

【问题讨论】:

【参考方案1】:

我认为答案是

有没有办法在网关中配置 Ocelot,以便在必要时挑战调用者接收 Windows 身份验证信息并将其传递给微服务?

问题是 Windows Authentication 是有状态的,服务器和客户端在同一个 Active Directory 中,你可以在 .NET Core Windows Authentication 中找到注释

Windows 身份验证是主要用于 Intranet 的有状态方案,其中代理或负载平衡器通常不处理客户端和服务器之间的流量。

微服务架构需要无状态而不是有状态(意味着服务器和客户端位于不同的 AD/OS/网络​​中)。而网关是微服务图中的一个无状态组件。

Ocelot 验证 Windows 用户身份的唯一方法是使用 Active Directory 联合服务 (ADFS) 和 OpenID Connect (OIDC) 或自行在 IIS 服务器中构建身份服务器。您可以阅读 ADFS 或 Azure AD 中的场景以了解更多详细信息。

此外,我对以下两个问题的回答:

    ,Ocelot 只是提供了插件功能来检测在允许请求通过下游之前必须包含哪些 JWT 声明。您可以构建自定义身份验证/授权中间件以允许/拒绝正确的上游。 没有,YARP在你的需求中和Ocelot的意思是一样的。

【讨论】:

但是在网关质询用户之后,它会以标头的形式接收身份。为什么 ocelot 不能将这些标头转发到 API 端点? 正如我所说,Windows 身份验证是有状态的,主要问题是该机制属于 IIS 服务器和 Windows 操作系统。两者都必须加入同一个 AD、Network 。该机制不仅仅是获取Form Header,它要求Web服务器认证机制支持网络级别的Windows认证。假设您有 Web 应用程序(客户端)、网关(代理)和 Api(Web 服务)。如果要通过网关和 Api 执行请求,它们必须保持在同一个网络、同一个 AD 上。这一点在微服务中是一个不好的做法 此外,用户不仅在网关级别进行身份验证,而且在 API 级别进行身份验证。与 SSO 相比,Windows 身份验证设置此方案更为复杂。 SSO 只需要使用 JWT 来传递服务器,服务器可以在没有第三方组件的情况下对 JWT 本身进行身份验证,而 Windows 身份验证要求服务器必须通过与 AD Server 通信来进行身份验证 感谢您的回答。我接受答案。

以上是关于如何使用 Ocelot 在 .Net Core API 网关中实现 Windows 身份验证,以便所有下游服务都可以访问 IWindowsPrincipal?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ocelot.json 路由 asp.net core 中发布 json body

.Net Core 基础学习笔记 Ocelot网关配置使用

.net core使用ocelot---第一篇 简单使用

.Net Core with 微服务

将 Ocelot 16.0 与 ASP.Net Core 3.1 集成不起作用,因为我需要将 Swagger 与 Ocelot 一起使用

asp.net core网关Ocelot的简单介绍& Ocelot集成Identity认证