I have been working on a project recently. It was an ASP .net core MVC plugin to our application. The plugin would connect to an Identity Server 4 to authenticate the user before allowing them access to the plugin.
I followed the tutorials on identity server website exactly yet i was getting this strange error message from Kong
[wp_ad_camp_3]
Headers to big
upstream sent too big header while reading response header from upstream
Fast forward a few hours. The problem was that the cookie returned by Identity server 4 was huge. The cookiechunker was chomping it up into 4000 kb bites and there were two of them so that gave me headers grater than 8000 kb which kong was not having.
Everything i read on line said that we should set up the default size in to be
proxy_buffers 8 16k; # Buffer pool = 8 buffers of 16k
proxy_buffer_size 16k; # 16k of buffers from pool used for headers
Our system admin was opposed to this his thinking was that it would continue to grow and then he would have to set it up again.
So i went looking for another solution. Which i found within this article Cookie size and cookie authentication in ASP.NET Core and this Git project MemoryCacheTicketStore.cs
Solution
The Cookie authentication has an option called SessionStore. BINGO! This allows us to store the it as a session rather than in the headers!
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options => options.SessionStore = new MemoryCacheTicketStore())
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = Configuration["ServiceSettings:IdentityServerEndpoint"];
options.RequireHttpsMetadata = false;
options.ClientId = Configuration["ServiceSettings:ClientId"];
options.ClientSecret = Configuration["ServiceSettings:secret"];
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("testapi");
options.Scope.Add("offline_access");
});
[wp_ad_camp_5]
public class MemoryCacheTicketStore : ITicketStore
{
private readonly int _expireInHours = 1;
private const string KeyPrefix = "AuthSessionStore-";
private IMemoryCache _cache;
public MemoryCacheTicketStore()
{
_cache = new MemoryCache(new MemoryCacheOptions());
}
public async Task StoreAsync(AuthenticationTicket ticket)
{
var key = $"{KeyPrefix}{Guid.NewGuid()}";
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(_expireInHours));
_cache.Set(key, ticket, options);
return Task.FromResult(0);
}
public Task RetrieveAsync(string key)
{
_cache.TryGetValue(key, out AuthenticationTicket ticket);
return Task.FromResult(ticket);
}
public Task RemoveAsync(string key)
{
_cache.Remove(key);
return Task.FromResult(0);
}
}
Conclusion
If you are having an issue with the size of your headers in Identity Server 4 it is possible to store the data as a season rather than in headers. You will need to create your own implementation of ITicketStore.
You were awesome!
We were havin the same problem here and your article helped a lot.
This was awesome!!!!
Really nice article saved the day!!!