Can I use MemoryCache
in an ITicketStore
to store an AuthenticationTicket
?
Background: My web app is using Cookie Authentication:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/Authentication/SignIn"),
LogoutPath = new PathString("/Authentication/SignOut"),
ReturnUrlParameter = "/Authentication/SignIn"
});
My web api handles the authorization process using access tokens (OAuth2).
Sometimes (on some browsers) the following exception is thrown:
An unhandled exception has occurred: The chunked cookie is incomplete. Only 1 of the expected 2 chunks were found, totaling 4021 characters. A client size limit may have been exceeded.
The cookie is obviously too big. This is strange, because I don't use many claims. All of them are default claims (nameidentifier, nonce, exp, etc.). I am now trying to implement my own ITicketStore
as a SessionStore
on the CookieAuthenticationOptions
. The AuthenticationTicket
will be stored in a MemoryCache
(like in this sample). I am very new to this whole topic and not sure, if this is a good approach and if the MemoryCache
is a valid solution.
ASP.NET Core provides a cookie authentication mechanism which on login serializes the user details in form of claims into an encrypted cookie and then sends this cookie back to the server on subsequent requests which gets validated to recreate the user object from claims and sets this user object in the HttpContext so ...
Cookie authentication uses HTTP cookies to authenticate client requests and maintain session information. It works as follows: The client sends a login request to the server.
SignInAsync(HttpContext, ClaimsPrincipal) Sign in a principal for the default authentication scheme. The default scheme for signing in can be configured using DefaultSignInScheme. SignInAsync(HttpContext, ClaimsPrincipal, AuthenticationProperties) Sign in a principal for the default authentication scheme.
SameSite is an IETF draft standard designed to provide some protection against cross-site request forgery (CSRF) attacks. Originally drafted in 2016, the draft standard was updated in 2019.
Can I use
MemoryCache
in anITicketStore
to store anAuthenticationTicket
?
Absolutely, here is the implementation that I have been using for nearly a year.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "App.Cookie",
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/Authentication/SignIn"),
LogoutPath = new PathString("/Authentication/SignOut"),
ReturnUrlParameter = "/Authentication/SignIn",
SessionStore = new MemoryCacheStore(cache)
});
The implementation of the MemoryCacheStore
looks like this, and it followed the example that you shared:
public class MemoryCacheStore : ITicketStore
{
private const string KeyPrefix = "AuthSessionStore-;
private readonly IMemoryCache _cache;
public MemoryCacheStore(IMemoryCache cache)
{
_cache = cache;
}
public async Task<string> StoreAsync(AuthenticationTicket ticket)
{
var key = KeyPrefix + Guid.NewGuid();
await RenewAsync(key, ticket);
return key;
}
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
// https://github.com/aspnet/Caching/issues/221
// Set to "NeverRemove" to prevent undesired evictions from gen2 GC
var options = new MemoryCacheEntryOptions
{
Priority = CacheItemPriority.NeverRemove
};
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
{
options.SetAbsoluteExpiration(expiresUtc.Value);
}
options.SetSlidingExpiration(TimeSpan.FromMinutes(60));
_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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With