OAuth Bearer Access Token 滑动过期
OAuth Bearer Access Token sliding expiration
假设我们使用 OAuth Bearer 令牌来保护我们的 API。有一个带有 OWIN 中间件的 NuGet 包可以为我们做这件事:https://www.nuget.org/packages/Microsoft.Owin.Security.OAuth.
Everethig 看起来很棒,直到提出有关 访问令牌过期的问题 - 我们不想强迫用户一遍又一遍地重新登录。据我了解,有三种基本方法:
- 使访问令牌到期时间非常长(例如 1 个月)
- 使用 OAuth 刷新令牌给身份验证服务器和用户应用程序代码增加了很多困难(在下面的文章 http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/ 中描述)
我很好奇是否可以创建需要即将过期的访问令牌的端点,并使用新的访问令牌进行响应以模拟 OAuth 访问令牌的滑动过期?
警告!如果您不能 100% 确定您的应用程序保证(这是不可能的)访问令牌不能被破坏(例如,XSS漏洞允许窃取访问令牌)。在此解决方案中,一旦访问令牌泄露,它可用于无限期延长访问。 OAuth 刷新令牌恰好解决了这个问题,在很短的时间内(通常大约 15 分钟)限制访问以防泄露访问令牌。
[Authorize]
public class RefreshTokenController : ApiController
{
[HttpGet]
public HttpResponseMessage ReissueToken()
{
// just use old identity
var identity = ((ClaimsPrincipal)User).Identity as ClaimsIdentity;
var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
DateTimeOffset currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.AddMinutes(30);
string token = Startup.OAuthBearerAuthOptions.AccessTokenFormat.Protect(ticket);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ObjectContent<object>(new
{
accessToken = token,
expiresIn = (int)((ticket.Properties.ExpiresUtc.Value - ticket.Properties.IssuedUtc.Value).TotalSeconds),
}, Configuration.Formatters.JsonFormatter)
};
}
}
假设我们使用 OAuth Bearer 令牌来保护我们的 API。有一个带有 OWIN 中间件的 NuGet 包可以为我们做这件事:https://www.nuget.org/packages/Microsoft.Owin.Security.OAuth.
Everethig 看起来很棒,直到提出有关 访问令牌过期的问题 - 我们不想强迫用户一遍又一遍地重新登录。据我了解,有三种基本方法:
- 使访问令牌到期时间非常长(例如 1 个月)
- 使用 OAuth 刷新令牌给身份验证服务器和用户应用程序代码增加了很多困难(在下面的文章 http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/ 中描述)
我很好奇是否可以创建需要即将过期的访问令牌的端点,并使用新的访问令牌进行响应以模拟 OAuth 访问令牌的滑动过期?
警告!如果您不能 100% 确定您的应用程序保证(这是不可能的)访问令牌不能被破坏(例如,XSS漏洞允许窃取访问令牌)。在此解决方案中,一旦访问令牌泄露,它可用于无限期延长访问。 OAuth 刷新令牌恰好解决了这个问题,在很短的时间内(通常大约 15 分钟)限制访问以防泄露访问令牌。
[Authorize]
public class RefreshTokenController : ApiController
{
[HttpGet]
public HttpResponseMessage ReissueToken()
{
// just use old identity
var identity = ((ClaimsPrincipal)User).Identity as ClaimsIdentity;
var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
DateTimeOffset currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.AddMinutes(30);
string token = Startup.OAuthBearerAuthOptions.AccessTokenFormat.Protect(ticket);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ObjectContent<object>(new
{
accessToken = token,
expiresIn = (int)((ticket.Properties.ExpiresUtc.Value - ticket.Properties.IssuedUtc.Value).TotalSeconds),
}, Configuration.Formatters.JsonFormatter)
};
}
}