我可以在MemoryCache
中使用ITicketStore
来存储AuthenticationTicket
吗?
背景:我的网络应用正在使用Cookie身份验证:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/Authentication/SignIn"),
LogoutPath = new PathString("/Authentication/SignOut"),
ReturnUrlParameter = "/Authentication/SignIn"
});
我的网络API使用访问令牌(OAuth2)处理授权过程。
有时(在某些浏览器上)会抛出以下异常:
发生了未处理的异常:分块的cookie不完整。仅发现预期的2个块中的1个,总共4021个字符。可能已超出客户端大小限制。
cookie显然太大了。这很奇怪,因为我不会使用很多说法。所有这些都是默认声明(nameidentifier,nonce,exp等)。我现在正尝试在ITicketStore
上将SessionStore
作为CookieAuthenticationOptions
实施。 AuthenticationTicket
将存储在MemoryCache
中(如此sample)。我对这整个主题都很陌生,不确定,如果这是一个好的方法,并且MemoryCache
是一个有效的解决方案。
答案 0 :(得分:9)
我可以在
MemoryCache
中使用ITicketStore
来存储AuthenticationTicket
吗?
当然,这是我近一年来一直在使用的实现。
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)
});
MemoryCacheStore
的实现如下所示,并且跟随您共享的the example:
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);
}
}