服务器上托管的Net WebApi应用程序。 我想实现基于令牌的方法以进行授权。 因此我写了一个TokenProvider和一个RefreshTokenProvider。 我将访问令牌设置为在10分钟后过期,刷新令牌在1天后过期。 但不知何故,刷新令牌在20分钟后到期。我已经研究过这个问题。由于这个问题,我在webconfig中手动设置了机器密钥,因此在应用程序池被回收后,令牌仍然可用,但这并没有解决问题。
我目前将刷新令牌存储在concurrentdictionary中。这不好吗?我应该将它存储在数据库中吗?
AuthorizationServerProvider(刷新令牌部分):
public override async Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach(KeyValuePair<string, string> property in context.Properties.Dictionary)
{
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}
}
public override async Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
{
var newIdentity = new ClaimsIdentity(context.Ticket.Identity);
newIdentity.AddClaim(new Claim("newClaim", "refreshToken"));
var newTicket = new AuthenticationTicket(newIdentity, context.Ticket.Properties);
context.Validated(newTicket);
}
SimpleRefreshTokenProvider:
private static ConcurrentDictionary<string, AuthenticationTicket> refreshTokens =
new ConcurrentDictionary<string, AuthenticationTicket>();
protected readonly log4net.ILog log;
public SimpleRefreshTokenProvider()
{
this.log = log4net.LogManager.GetLogger(GetType());
}
public void Create(AuthenticationTokenCreateContext context)
{
throw new NotImplementedException();
}
public async Task CreateAsync(AuthenticationTokenCreateContext context)
{
var guid = Guid.NewGuid().ToString();
var refreshTokenDaysLifeTime = 1;
AuthenticationProperties refreshTokenProperties = new AuthenticationProperties(context.Ticket.Properties.Dictionary);
refreshTokenProperties.IssuedUtc = context.Ticket.Properties.IssuedUtc;
refreshTokenProperties.ExpiresUtc = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenDaysLifeTime*(60*24)));
context.Ticket.Properties.IssuedUtc = refreshTokenProperties.IssuedUtc;
context.Ticket.Properties.ExpiresUtc = refreshTokenProperties.ExpiresUtc;
AuthenticationTicket refreshTokenTicket =
new AuthenticationTicket(context.Ticket.Identity, refreshTokenProperties);
refreshTokens.TryAdd(guid, refreshTokenTicket);
this.log.Info($"Added refresh token: {guid}. Should expire on {refreshTokenTicket.Properties.ExpiresUtc}");
context.SetToken(guid);
}
public void Receive(AuthenticationTokenReceiveContext context)
{
throw new NotImplementedException();
}
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
AuthenticationTicket ticket;
if (refreshTokens.TryRemove(context.Token, out ticket))
{
this.log.Info($"Used refresh token to receive access token: {context.Token}");
context.SetTicket(ticket);
}
}
我很感激每一个提示,谢谢你们。)
答案 0 :(得分:0)
最后解决方案非常愚蠢。
我实际上想阻止池回收我保留刷新令牌的字典。由于它是由提供者托管的,我无法调整回收时间,因此每次刷新池时,我都丢失了所有刷新令牌。 最后,我只是将刷新令牌存储在数据库中。