.NetWebApi 刷新令牌在 20 分钟后过期

.NetWebApi refresh token expires after 20 minutes

托管在服务器上的 Net WebApi 应用程序。 我想实施基于令牌的方法以进行授权。 因此我写了一个 TokenProvider 和一个 RefreshTokenProvider。 我将访问令牌设置为 10 分钟后过期,将刷新令牌设置为 1 天后过期。 但不知何故,刷新令牌会在 20 分钟后过期。我已经研究过这个问题。由于问题我在webconfig中手动设置了machine key,所以应用池回收后token还是可用的,没有解决问题。

我目前将刷新令牌存储在并发字典中。不好吗?我应该将它存储在数据库中吗?

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);
  }
}

感谢每一个提示谢谢:)

最后解决的很蠢

我实际上是想防止池回收我保存刷新令牌的字典。由于它由提供商托管,我无法调整回收时间,所以每次池刷新时,我都丢失了刷新令牌。 最后,我只是将刷新令牌存储在数据库中。