为什么交换RefreshToken请求到达时调用AuthenticationTokenProvider的CreateAsync?
Why CreateAsync of AuthenticationTokenProvider Is Called When Request to Exchange RefreshToken Arrives?
我有 AuthenticationTokenProvider
抽象的自定义实现。我正在使用它有两种方法可以覆盖:CreateAsync
、ReceiveAsync
.
在 OAuthAuthorizationServerOptions
中,我将 RefreshTokenProvider
设置为我的自定义 AuthenticationTokenProvider
实现。
我的访问令牌将在 20 分钟后过期。我的刷新令牌将在 24 小时后过期。当访问令牌过期时,请求附带 grant_type=refresh_token
包含刷新令牌。我观察到 ReceiveAsync
被调用。有设置Ticket
属性 of AuthenticationTokenReceiveContext
的逻辑。但是之后调用了CreateAsync
方法,这里有在AuthenticationTokenCreateContext
中设置token的逻辑。 AuthenticationTokenCreateContext
的Ticket
属性好像不是我之前在ReceiveAsync
方法里设置的那个
因此,我收到了带有新访问令牌和刷新令牌的响应。我不希望每次我想交换我的访问令牌时都重新发布刷新令牌,我已经有一个有效期为 24 小时的令牌。
最终我找到了如何回答我的问题。我可以利用 OwinContext.Environment
来存储一个标志,该标志告诉我的刷新令牌尚未过期,因此无需创建新令牌。
public class RefreshTokenProvider : AuthenticationTokenProvider
{
private const string IsRefreshTokenExpiredName = "IsRefreshTokenExpired";
#region ctor
public RefreshTokenProvider()
{
}
#endregion
public async override Task CreateAsync(AuthenticationTokenCreateContext context)
{
if (!context.OwinContext.Environment.ContainsKey(IsRefreshTokenExpiredName) || (bool)context.OwinContext.Environment[IsRefreshTokenExpiredName])
{
var hours = int.Parse(ConfigurationManager.AppSettings["RefreshTokenExpirationHours"]);
var now = DateTime.UtcNow;
context.Ticket.Properties.IssuedUtc = now;
context.Ticket.Properties.ExpiresUtc = now.AddHours(hours);
context.SetToken(context.SerializeTicket());
}
}
public async override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { ConfigurationManager.AppSettings["CorsOrigins"] });
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Method", new[] { "POST" });
context.DeserializeTicket(context.Token);
if (context.Ticket.Properties.ExpiresUtc > DateTime.UtcNow)
context.OwinContext.Environment[IsRefreshTokenExpiredName] = false;
}
}
我有 AuthenticationTokenProvider
抽象的自定义实现。我正在使用它有两种方法可以覆盖:CreateAsync
、ReceiveAsync
.
在 OAuthAuthorizationServerOptions
中,我将 RefreshTokenProvider
设置为我的自定义 AuthenticationTokenProvider
实现。
我的访问令牌将在 20 分钟后过期。我的刷新令牌将在 24 小时后过期。当访问令牌过期时,请求附带 grant_type=refresh_token
包含刷新令牌。我观察到 ReceiveAsync
被调用。有设置Ticket
属性 of AuthenticationTokenReceiveContext
的逻辑。但是之后调用了CreateAsync
方法,这里有在AuthenticationTokenCreateContext
中设置token的逻辑。 AuthenticationTokenCreateContext
的Ticket
属性好像不是我之前在ReceiveAsync
方法里设置的那个
因此,我收到了带有新访问令牌和刷新令牌的响应。我不希望每次我想交换我的访问令牌时都重新发布刷新令牌,我已经有一个有效期为 24 小时的令牌。
最终我找到了如何回答我的问题。我可以利用 OwinContext.Environment
来存储一个标志,该标志告诉我的刷新令牌尚未过期,因此无需创建新令牌。
public class RefreshTokenProvider : AuthenticationTokenProvider
{
private const string IsRefreshTokenExpiredName = "IsRefreshTokenExpired";
#region ctor
public RefreshTokenProvider()
{
}
#endregion
public async override Task CreateAsync(AuthenticationTokenCreateContext context)
{
if (!context.OwinContext.Environment.ContainsKey(IsRefreshTokenExpiredName) || (bool)context.OwinContext.Environment[IsRefreshTokenExpiredName])
{
var hours = int.Parse(ConfigurationManager.AppSettings["RefreshTokenExpirationHours"]);
var now = DateTime.UtcNow;
context.Ticket.Properties.IssuedUtc = now;
context.Ticket.Properties.ExpiresUtc = now.AddHours(hours);
context.SetToken(context.SerializeTicket());
}
}
public async override Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { ConfigurationManager.AppSettings["CorsOrigins"] });
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Method", new[] { "POST" });
context.DeserializeTicket(context.Token);
if (context.Ticket.Properties.ExpiresUtc > DateTime.UtcNow)
context.OwinContext.Environment[IsRefreshTokenExpiredName] = false;
}
}