.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);
}
}
感谢每一个提示谢谢:)
最后解决的很蠢
我实际上是想防止池回收我保存刷新令牌的字典。由于它由提供商托管,我无法调整回收时间,所以每次池刷新时,我都丢失了刷新令牌。
最后,我只是将刷新令牌存储在数据库中。
托管在服务器上的 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);
}
}
感谢每一个提示谢谢:)
最后解决的很蠢
我实际上是想防止池回收我保存刷新令牌的字典。由于它由提供商托管,我无法调整回收时间,所以每次池刷新时,我都丢失了刷新令牌。 最后,我只是将刷新令牌存储在数据库中。