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

时间:2016-03-07 17:16:08

标签: .net oauth asp.net-web-api2 token

服务器上托管的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);
  }
}

我很感激每一个提示,谢谢你们。)

1 个答案:

答案 0 :(得分:0)

最后解决方案非常愚蠢。

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