我有一个连接到Identity Server 4身份服务器的Asp .net mvc应用程序。当我发布应用程序时,我对此错误感到不满。
上游在从上游读取响应头时发送了太大的头文件
我跟踪过这个upstream sent too big header while reading response header from upstream
我无法改变配置,系统管理员已声明我们需要缩小标头。
在看完之后我不得不同意这些标题有点广泛。
应用中的Startup.cs
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = Configuration["ServiceSettings:IdentityServerEndpoint"];
options.RequireHttpsMetadata = true;
options.ClientId = Configuration["ServiceSettings:ClientId"];
options.ClientSecret = Configuration["ServiceSettings:secret"];
options.Scope.Add("testapi");
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Events = new OpenIdConnectEvents()
{
OnRemoteFailure = ctx =>
{
_logger.LogCritical($"Remote Faliure: {ctx.Failure}");
ctx.HandleResponse();
return Task.FromResult(0);
}
};
});
我一直在寻找,我似乎无法找到限制这个巨大标题大小的方法。
答案 0 :(得分:2)
默认情况下,cookie包含加密的所有相关信息,因此在调用api时 - 您需要做的就是解密cookie并使用该信息。
然而,经常将所有内容存储在cookie本身中是不可取的,尤其是在存在大量相关信息的情况下。 Cookie随每次请求发送到您的api,如果它很大 - 很多(相同的)信息基本上是无用的来回发送。另外,正如您所看到的那样 - 在某些环境中,cookie的大小可能会成为一个限制因素。
因此,您不必在cookie本身中发送所有信息 - 您可以将该信息存储在其他位置,例如在服务器内存中,并且只在cookie本身中放置该信息的标识符。
您可以为此会话配置商店:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(o => o.SessionStore = new MemoryCacheTicketStore());
您可以在github上的asp.net examples找到示例MemoryCacheTicketStore
实现:
public class MemoryCacheTicketStore : ITicketStore
{
private const string KeyPrefix = "AuthSessionStore-";
private IMemoryCache _cache;
public MemoryCacheTicketStore()
{
_cache = new MemoryCache(new MemoryCacheOptions());
}
public async Task<string> StoreAsync(AuthenticationTicket ticket)
{
var guid = Guid.NewGuid();
var key = KeyPrefix + guid.ToString();
await RenewAsync(key, ticket);
return key;
}
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var options = new MemoryCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
{
options.SetAbsoluteExpiration(expiresUtc.Value);
}
options.SetSlidingExpiration(TimeSpan.FromHours(1)); // TODO: configurable.
_cache.Set(key, ticket, options);
return Task.FromResult(0);
}
public Task<AuthenticationTicket> RetrieveAsync(string key)
{
AuthenticationTicket ticket;
_cache.TryGetValue(key, out ticket);
return Task.FromResult(ticket);
}
public Task RemoveAsync(string key)
{
_cache.Remove(key);
return Task.FromResult(0);
}
}