认证限制了广泛的头部大小 [英] Authentication limit extensive header size

查看:257
本文介绍了认证限制了广泛的头部大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个连接到Identity Server 4身份服务器的Asp .net mvc应用程序。


$ b


上游在读取来自上游的响应标题时发送了太大的标题


我已经追踪到这个



看完后我必须同意这些标题有点广泛。

应用程序中的Startup.cs

  services.AddAuthentication(options => 
{
options.Default Scheme = 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($远程错误:{ctx.Failure});
ctx.HandleResponse();
return Task.FromResult(0);
}
};
});

我一直在寻找所有的东西,我似乎无法找到限制这个巨大的尺寸的方法头。

解决方案

默认情况下,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());

您可以在以下位置找到示例 MemoryCacheTicketStore 在github上的示例

  public class MemoryCacheTicketStore:ITicketStore 
{
private const string KeyPrefix =AuthSessionStore-;
private IMemoryCache _cache;
$ b $ public MemoryCacheTicketStore()
{
_cache = new MemoryCache(new MemoryCacheOptions());
}

公共异步任务< string> StoreAsync(AuthenticationTicket ticket)
{
var guid = Guid.NewGuid();
var key = KeyPrefix + guid.ToString();
等待RenewAsync(密钥,票证);
返回键;


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:可配置。

_cache.Set(key,ticket,options);

return Task.FromResult(0);
}

public Task< AuthenticationTicket> RetrieveAsync(字符串键)
{
AuthenticationTicket ticket;
_cache.TryGetValue(钥匙,出票);
返回Task.FromResult(ticket);


public Task RemoveAsync(string key)
{
_cache.Remove(key);
return Task.FromResult(0);
}
}


I have an Asp .net mvc app that connects to an Identity server 4 identity server. When i released the app I was fased with this error.

upstream sent too big header while reading response header from upstream

Which i have tracked to this upstream sent too big header while reading response header from upstream

I can not alter the config and sys admin has stated that we need to make the headers smaller.

After looking at that i would have to agree that these headers are a bit extensive.

Startup.cs in app

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);
                    }
                };
            });

I have been looking all over and i cant seem to find a way of limiting the size of this huge header.

解决方案

By default, cookie contains all relevant information, encrypted, so when call to your api is made - all you need to do is decrypt cookie and use that information.

However, often storing everything in a cookie itself is not desirable, especially if there is a lot of relevant information. Cookie is sent with every request to your api, and if it's big - a lot of (the same) information is sent back and forth basically for nothing. Plus as you see yourself - size of cookie might become a limiting factor in some environments.

So instead of sending all information in cookie itself - you can store that information somewhere else, for example in server memory, and place only identifier for that information in cookie itself.

You can configure store for session like this:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(o => o.SessionStore = new MemoryCacheTicketStore());

And you can find sample MemoryCacheTicketStore implementation at asp.net examples on github:

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);
    }
}

这篇关于认证限制了广泛的头部大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆