JWT Bearer token content length limited by some public firewall.

huangapple go评论65阅读模式
英文:

JWT Bearer token content length limited by some public firewall

问题

我们在JWT令牌大小方面存在问题。

我们目前使用Angular前端和IdentityServer4身份验证服务。一旦身份验证完成,下一个调用是通过userprofile端点检索用户声明。在这个调用中,我们将各种信息返回到HTTP请求头中的用户声明中(在Bearer令牌中)发送到Angular前端。

在某些防火墙上,启用了IPS(入侵防护系统,例如:Stormshield,Palo Alto,Azure)选项,并且使用HTTP协议时,请求会被过滤,并且令牌会被截断,出现令牌过长的错误消息。实际上,在IPS协议下,Bearer令牌的内容不能超过1000字节。

> 总结一下:
> 前端Angular -> 发送连接请求到IdentityServer4
> IdentityServer4 -> 响应OK
> 前端Angular -> 从IdentityServer4请求infousers路由
> IdentityServer4 -> 通过IProfileService.GetProfileDataAsync()通过Bearer令牌发送声明
> 防火墙 -> 拦截并打开数据包,检测到令牌太大,截断并重新编码
> 前端Angular -> 出现ERRCONRESET错误,因为HTTP头中的JWT令牌不一致。

是否有人遇到类似的问题?

您是否有减小JWT令牌大小的解决方案或想法?

Bearer和声明的实现和使用是否正确?

以下是一些配置:

IdentityServer的config.cs

新客户端
{
	ClientId = "myClient",
	ClientName = "myClientName",
	AccessTokenType = AccessTokenType.Jwt,
	AllowedGrantTypes = GrantTypes.Implicit,
	AllowAccessTokensViaBrowser = true,
	AlwaysSendClientClaims = true,
	AlwaysIncludeUserClaimsInIdToken = true,
	RequireConsent = false,
	RedirectUris = { urlClient },
	PostLogoutRedirectUris = { urlClient },
	AllowedCorsOrigins = { urlClient },
	AccessTokenLifetime = 86400,
	IdentityTokenLifetime = 86400,
	AllowedScopes =
	{
		IdentityServerConstants.StandardScopes.OpenId,
		IdentityServerConstants.StandardScopes.Profile,
		IdentityServerConstants.StandardScopes.Email,
		SomeConstant,
		SomeConstant,
		SomeConstant,
	}
}

IdentityServer的ConfigureServices()

services.ConfigureNonBreakingSameSiteCookies();
services.AddRazorPages().AddMvcOptions(options => options.EnableEndpointRouting = false).SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddSingleton(new ConfigurationIdentityServer("myUrl", _Configuration.GetSection("applicationServer").Get<ConfigurationApplicationServer>()));
services.AddSingleton<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();
	
var builder = services.AddIdentityServer()
	.AddInMemoryIdentityResources(Config.GetIdentityResources())
	.AddInMemoryApiScopes(Config.GetApiScopes())
	.AddRedirectUriValidator<MyUriValidator>();
builder.Services.AddSingleton<IUserRepository, UserRepository>();
builder.AddProfileService<CustomProfileService>();
builder.AddClientStore<CustomClientStore>();
	
services.AddScoped<IWireService, WireService>();
services.AddCors(setup => setup.AddDefaultPolicy(b => b.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
	
builder.AddCustomTokenRequestValidator<CustomTokenRequestValidator>();
builder.AddDeveloperSigningCredential();

以及Configure()

if (env.IsDevelopment())
	app.UseDeveloperExceptionPage();

app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseCors();
app.UseIdentityServer();
app.UseMvcWithDefaultRoute();
app.UseAuthentication();

JWT令牌的示例:

(JWT令牌内容,此部分已省略)

提前感谢您的建议。

英文:

We have an issue with JWT token sizes.

We currently have an Angular front-end and an authentication service via IdentityServer4. As soon as authentication is performed, the next call is to retrieve the user's claims via the userprofile endpoint. In this call, we return various information in the user claims in the HTTP request header (in the Bearer token) to the Angular front end.

On some firewalls, with the IPS (Intrusion Prevention System, ex: Stormshield, Palo alto, Azure) option active and the HTTP protocol, requests are filtered and the token is truncated with the error message that it is too long. In reality, the bearer token content under the IPS protocol cannot exceed 1000 bytes.

> To summarize:
> Front Angular -> Sends a connection request to IdentityServer4
> IdentityServer4 -> Responds OK
> Front Angular -> Request infousers route from IdentityServer4
> IdentityServer4 -> Sends claims through bearer token from IProfileService.GetProfileDataAsync()
> Firewall -> Intercepts and opens packets, detects that token is too large, truncates and re-encodes it
> Front Angular -> ERRCONRESET error because the JWT token is inconsistent in the HTTP header.

Has anyone encountered a similar problem?

Do you have a solution or an idea for reducing the size of the JWT token?

Is the implementation and use of the bearer and claims correct?

Here are a few configurations:

config.cs of IdentityServer:

new Client
{
	ClientId = &quot;myClient&quot;,
	ClientName = &quot;myClientName&quot;,
	AccessTokenType = AccessTokenType.Jwt,
	AllowedGrantTypes = GrantTypes.Implicit,
	AllowAccessTokensViaBrowser = true,
	AlwaysSendClientClaims = true,
	AlwaysIncludeUserClaimsInIdToken = true,
	RequireConsent = false,
	RedirectUris = { urlClient },
	PostLogoutRedirectUris = { urlClient },
	AllowedCorsOrigins = { urlClient },
	AccessTokenLifetime = 86400,
	IdentityTokenLifetime = 86400,
	AllowedScopes =
	{
		IdentityServerConstants.StandardScopes.OpenId,
		IdentityServerConstants.StandardScopes.Profile,
		IdentityServerConstants.StandardScopes.Email,
		SomeConstant,
		SomeConstant,
		SomeConstant,
	}
}

ConfigureServices() of IdentityServer:

services.ConfigureNonBreakingSameSiteCookies();
services.AddRazorPages().AddMvcOptions(options =&gt; options.EnableEndpointRouting = false).SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddSingleton(new ConfigurationIdentityServer(&quot;myUrl&quot;, _Configuration.GetSection(&quot;applicationServer&quot;).Get&lt;ConfigurationApplicationServer&gt;()));
services.AddSingleton&lt;IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator&gt;();

var builder = services.AddIdentityServer()
	.AddInMemoryIdentityResources(Config.GetIdentityResources())
	.AddInMemoryApiScopes(Config.GetApiScopes())
	.AddRedirectUriValidator&lt;MyUriValidator&gt;();
builder.Services.AddSingleton&lt;IUserRepository, UserRepository&gt;();
builder.AddProfileService&lt;CustomProfileService&gt;();
builder.AddClientStore&lt;CustomClientStore&gt;();

services.AddScoped&lt;IWireService, WireService&gt;();
services.AddCors(setup =&gt; setup.AddDefaultPolicy(b =&gt; b.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));

builder.AddCustomTokenRequestValidator&lt;CustomTokenRequestValidator&gt;();
builder.AddDeveloperSigningCredential();

And Configure():

if (env.IsDevelopment())
	app.UseDeveloperExceptionPage();

app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseCors();
app.UseIdentityServer();
app.UseMvcWithDefaultRoute();
app.UseAuthentication();

An example of a JWT token:

{
  &quot;alg&quot;: &quot;RS256&quot;,
  &quot;kid&quot;: &quot;F5B66993EBF31790213A4D52AD81F98E&quot;,
  &quot;typ&quot;: &quot;at+jwt&quot;
}
{
  &quot;nbf&quot;: 1687784431,
  &quot;exp&quot;: 1687870831,
  &quot;iss&quot;: &quot;myAuthUrl&quot;,
  &quot;client_id&quot;: &quot;myClient&quot;,
  &quot;sub&quot;: &quot;1&quot;,
  &quot;auth_time&quot;: 1687784425,
  &quot;idp&quot;: &quot;local&quot;,
  &quot;profile&quot;: &quot;Admin Admin&quot;,
  &quot;key0&quot;: &quot;Admin&quot;,
  &quot;key1&quot;: &quot;1&quot;,
  &quot;key2&quot;: &quot;1&quot;,
  &quot;key3&quot;: &quot;True&quot;,
  &quot;nb&quot;: &quot;0&quot;,
  &quot;jti&quot;: &quot;3B8CDF16E4AC8490B5F9C2E0C5D7A6CD&quot;,
  &quot;sid&quot;: &quot;920D817F645FF497490E6AC9D25D1C67&quot;,
  &quot;iat&quot;: 1687784431,
  &quot;scope&quot;: [
    &quot;openid&quot;,
    &quot;profile&quot;,
    &quot;email&quot;,
    &quot;SomeConstant&quot;,
    &quot;SomeConstant&quot;,
    &quot;SomeConstant&quot;
  ],
  &quot;amr&quot;: [
    &quot;pwd&quot;
  ]
}

Thanks in advance for your ideas

答案1

得分: 1

1000字节是一个非常严格的限制。您(非常短)的示例令牌具有约600个字符,然后添加base64开销约25%,您将在令牌中获得约800个字符。

有几种选择:

  • 使用简短的声明名称和简短的声明值,例如,使用值1而不是&quot;True&quot;,使用C#枚举而不是固定字符串,使用单个字符的声明名称。字符串常量会很快增加令牌的大小;
  • 不要将非关键的声明放入令牌中,并从数据库中获取其他信息。您可以创建一个额外的端点,在需要时返回扩展的用户信息;
  • 而不是多个声明,您可以尝试将所有内容编码到单个以protobuf格式(或任何其他二进制格式)的“uber-声明”中,并根据需要使用其中一种压缩算法进行压缩(如果有意义,请记住base64开销)。
英文:

1000 bytes is a very strict limitation. Your (very short) sample token has ~600 chars, then add base64 overhead ~25% and you have ~800 chars in token.

There are several options:

  • use short claim names and short claim values, e.g. use value 1 instead of &quot;True&quot;, use C# enums instead of fixed strings, use single char claim names. String constants very quickly increase size of the token;
  • do not put non-critical claims into token and get other information from DB. You can create an additional endpoint that returns extended user information when needed;
  • Instead of multiple claims, you can try to encode everything into single "uber-claim" in protobuf format (or any other binary format) and optionally compress it using one of the compression algorithms (if it makes sense, keep in mind base64 overhead).

答案2

得分: 0

有一个在IdentityServer中的"reference tokens"概念,它允许你获得非常短的访问令牌。

在此处阅读更多信息:https://docs.duendesoftware.com/identityserver/v6/tokens/reference/

英文:

There is a concept of reference tokens in IdentityServer that allows you to get really short access tokens.

Read more about it here https://docs.duendesoftware.com/identityserver/v6/tokens/reference/

huangapple
  • 本文由 发表于 2023年6月26日 22:17:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76557545.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定