我在.NET Core中实现了自己的ITicketStore实现,它处理在redis数据库中存储会话cookie。我的键是一个简单的指南。
public async Task<string> StoreAsync(AuthenticationTicket ticket)
{
var log = new StringWriter();
var guid = Guid.NewGuid();
var key = "MyCustomCache"+ guid.ToString();
await RenewAsync(key, ticket);
return key;
}
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
{
options.SetAbsoluteExpiration(expiresUtc.Value);
}
byte[] val = SerializeToBytes(ticket);
_cache.Set(key, val, options);
return Task.FromResult(0);
}
然而在浏览器中,当我检查cookie的值时,它似乎以某种方式被加密了(而不是我生成的guid)。
当cookie被传递到我的应用程序时,我注意到它已经被转换回我在StoreAsync中创建的原始值。
public Task<AuthenticationTicket> RetrieveAsync(string key)
{
// Key passed in here will not be the value in the image above. Instead it will be what was
// generated in StoreAsync
AuthenticationTicket ticket;
byte[] bytes = null;
bytes = _cache.Get(key);
ticket = DeserializeFromBytes(bytes);
return Task.FromResult(ticket);
}
.NET Core到底对我的密钥做了什么加密处理?这是否会影响我的应用程序的负载平衡能力?我知道在默认的会话存储机制中,.NET Core使用每台机器的动态密钥来加密会话cookie。
认证cookie被默认的数据保护加密。
这里是密钥被添加到cookie中的地方 (源头):
if (Options.SessionStore != null)
{
if (_sessionKey != null)
{
await Options.SessionStore.RemoveAsync(_sessionKey);
}
_sessionKey = await Options.SessionStore.StoreAsync(ticket);
var principal = new ClaimsPrincipal(
new ClaimsIdentity(
new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) },
Options.ClaimsIssuer));
ticket = new AuthenticationTicket(principal, null, Scheme.Name);
}
var cookieValue = Options.TicketDataFormat.Protect(ticket, GetTlsTokenBinding());
当切换到SessionStore时,会话密钥只是作为一个要求添加,然后cookie就会受到保护。