[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网关后面?