[Authorize]对ocelot网关后面的内部服务没有用吗?

Posted

技术标签:

【中文标题】[Authorize]对ocelot网关后面的内部服务没有用吗?【英文标题】:Is [Authorize] useless for internal service that behind the ocelot gateway? 【发布时间】:2020-10-22 20:10:28 【问题描述】:

鉴于我已经根据ocelot document 设置了ocelot 并与IdentityServer4 集成,我是否应该删除[Authorize] 属性和身份验证相关代码(例如@987654324 上的UseAuthentication 中间件@) 来自那些内部服务?

如果去掉[Authorize]和相关代码,那些内部服务怎么能得到User.Claims呢?以及如何保护这些服务免受来自内部的线程的影响?

如果保留[Authroize]和相关代码,那么IdentityServer4与Ocelot集成的意义何在?我能看到的唯一好处是防止无效请求到达内部服务。


长篇大论:

我设置了 Ocelot 网关并与 IdentityServer4 集成。我所有的内部 Api 服务(例如 ServiceA、ServiceB)都在网关后面。

为了保证内部服务的安全,我设置了AuthenticationOptions,正如ocelot官方文档所说的那样。

例如ocelot网关配置:


  "ReRoutes": [
    
      "DownstreamPathTemplate": "/api/version/everything",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        
          "Host": "localhost",
          "Port": 5001
        
      ],
      "LoadBalancerOptions": 
        "Type": "LeastConnection"
      ,
      "UpstreamPathTemplate": "/serviceA/api/version/everything",
      "UpstreamHttpMethod": [],
      "AuthenticationOptions": 
        "AuthenticationProviderKey": "ApiGwAuth",
        "AllowedScopes": []
      
    
  ]

public void ConfigureServices(IServiceCollection services)

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
    services.AddAuthentication()
        .AddJwtBearer("ApiGwAuth", x =>
        
            x.Authority = Configuration["IdentityServiceSettings:Url"];
            x.RequireHttpsMetadata = false;
            x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
            
                ValidAudiences = new[]  "serviceA", "serviceB" 
            ;
        );

    services.AddOcelot(Configuration);

需要保护的serviceA:

[Authorize]
[HttpGet]
public ActionResult GetProtectedInfo()

     // e.g.     
     return Ok(User.Claims.Select(itm => itm.ToString()));

如果[Authorize]和相关代码被删除,如何获取User.Claims

【问题讨论】:

this.User.Identity 是空的吗? @AndrewE 是的,User.Identity 为空。 您是否尝试过向addJwtBeater 添加一个事件,例如options.Events = new JwtBearerEvents()OnTokenValidated = async context =>await Task.Yield();, 并确认那里有一个jwt 令牌?如果是这样,您可以创建自己的 this.User.Identity 也可以将 [Authorize] 更改为 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] 【参考方案1】:

如果您删除 UseAuthentication(),您将丢失 User.Identity。 如果您想生成 User.Identity 但没有 Ocelot 通过的 JWT 验证,请尝试以下操作:

配置服务

      services.AddAuthentication(x =>
        
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        )
        .AddJwtBearer(x =>
        
            x.RequireHttpsMetadata = false;
            x.SaveToken = true;
            x.TokenValidationParameters = CreateTokenValidationParameters();
        );

配置

app.UseAuthentication();

private TokenValidationParameters CreateTokenValidationParameters() //we ignore token validation because gateway validates it
    
        var result = new TokenValidationParameters
        
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateIssuerSigningKey = false,
            SignatureValidator = delegate (string token, TokenValidationParameters parameters)
            
                var jwt = new JwtSecurityToken(token);
                return jwt;
            ,
            RequireExpirationTime = true,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero,
        ;
        result.RequireSignedTokens = false;
        return result;
    

【讨论】:

以上是关于[Authorize]对ocelot网关后面的内部服务没有用吗?的主要内容,如果未能解决你的问题,请参考以下文章

怎么把IdentityServer放到Ocelot网关后面?

怎么把IdentityServer放到Ocelot网关后面?

AKS 中的 Ocelot API 网关实现

404错误:尝试在docker内部部署ocelot网关调用微服务

[置顶] 基于.NET平台的Ocelot网关框架教程汇总

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