我正在使用Visual Studio 2013随附的Web Api 2模板,该模板具有一些OWIN中间件来进行用户身份验证等。
在中,OAuthAuthorizationServerOptions我注意到OAuth2服务器已设置为发放在14天内到期的令牌
OAuthAuthorizationServerOptions
OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/api/token"), Provider = new ApplicationOAuthProvider(PublicClientId,UserManagerFactory) , AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), AllowInsecureHttp = true };
这不适合我的最新项目。我想分发短暂的bearer_tokens,可以使用refresh_token
refresh_token
我已经进行了大量谷歌搜索,找不到任何有用的信息。
这就是我设法取得的成就。我现在已经达到“现在就做WTF”这一点。
我写了一个RefreshTokenProvider实现类IAuthenticationTokenProvider的RefreshTokenProvider属性OAuthAuthorizationServerOptions:
RefreshTokenProvider
IAuthenticationTokenProvider
public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider { private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>(); public async Task CreateAsync(AuthenticationTokenCreateContext context) { var guid = Guid.NewGuid().ToString(); _refreshTokens.TryAdd(guid, context.Ticket); // hash?? context.SetToken(guid); } public async Task ReceiveAsync(AuthenticationTokenReceiveContext context) { AuthenticationTicket ticket; if (_refreshTokens.TryRemove(context.Token, out ticket)) { context.SetTicket(ticket); } } public void Create(AuthenticationTokenCreateContext context) { throw new NotImplementedException(); } public void Receive(AuthenticationTokenReceiveContext context) { throw new NotImplementedException(); } } // Now in my Startup.Auth.cs OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/api/token"), Provider = new ApplicationOAuthProvider(PublicClientId,UserManagerFactory) , AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(2), AllowInsecureHttp = true, RefreshTokenProvider = new RefreshTokenProvider() // This is my test };
因此,现在当有人请求bearer_token我时refresh_token,我正在发送,这很棒。
bearer_token
因此,现在如何使用该refresh_token获取一个新的bearer_token(大概需要将请求发送到具有某些特定HTTP标头的令牌端点)?
刚输入时大声思考…我应该处理我的refresh_token到期SimpleRefreshTokenProvider吗?客户将如何获得新的refresh_token?
SimpleRefreshTokenProvider
我真的可以使用一些阅读材料/文档,因为我不想弄错这一点,而是想遵循某种标准。
刚刚使用Bearer(以下称为access_token)和Refresh Tokens实现了我的OWIN服务。我对此的见解是,您可以使用不同的流程。因此,这取决于您要使用的流程来设置access_token和refresh_token到期时间。
我将在下面描述两个 流程 A 和 B (我建议您要拥有的是流程B):
A) access_token和refresh_token的到期时间与默认情况下的1200秒或20分钟相同。此流程需要您的客户端首先发送带有登录数据的client_id和client_secret以获得access_token,refresh_token和expiration_time。借助refresh_token,现在可以在20分钟内获取一个新的access_token(或在OAuthAuthorizationServerOptions中将AccessTokenExpireTimeSpan设置为的任何值)。由于access_token和refresh_token的到期时间相同,因此您的客户有责任在到期之前获得新的access_token!例如,您的客户端可以使用主体向令牌端点发送刷新POST调用(备注:您应在生产环境中使用https)
grant_type=refresh_token&client_id=xxxxxx&refresh_token=xxxxxxxx-xxxx-xxxx-xxxx-xxxxx
例如在19分钟后获得新令牌,以防止令牌过期。
B) 在此流程中,您希望access_token的短期到期,而refresh_token的长期到期。假设出于测试目的,您将access_token设置为在10秒(AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(10))内到期,并将refresh_token设置为5分钟。现在涉及到设置refresh_token的到期时间的有趣部分:您可以在SimpleRefreshTokenProvider类的createAsync函数中执行以下操作:
AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(10)
var guid = Guid.NewGuid().ToString(); //copy properties and set the desired lifetime of refresh token var refreshTokenProperties = new AuthenticationProperties(context.Ticket.Properties.Dictionary) { IssuedUtc = context.Ticket.Properties.IssuedUtc, ExpiresUtc = DateTime.UtcNow.AddMinutes(5) //SET DATETIME to 5 Minutes //ExpiresUtc = DateTime.UtcNow.AddMonths(3) }; /*CREATE A NEW TICKET WITH EXPIRATION TIME OF 5 MINUTES *INCLUDING THE VALUES OF THE CONTEXT TICKET: SO ALL WE *DO HERE IS TO ADD THE PROPERTIES IssuedUtc and *ExpiredUtc to the TICKET*/ var refreshTokenTicket = new AuthenticationTicket(context.Ticket.Identity, refreshTokenProperties); //saving the new refreshTokenTicket to a local var of Type ConcurrentDictionary<string,AuthenticationTicket> // consider storing only the hash of the handle RefreshTokens.TryAdd(guid, refreshTokenTicket); context.SetToken(guid);
现在,您的客户端可以在令牌access_token过期时将带有refresh_token的POST调用发送到令牌端点。调用的正文部分可能如下所示:grant_type=refresh_token&client_id=xxxxxx&refresh_token=xxxxxxxx- xxxx-xxxx-xxxx-xx
access_token
grant_type=refresh_token&client_id=xxxxxx&refresh_token=xxxxxxxx- xxxx-xxxx-xxxx-xx
重要的一件事是,您不仅可能要在CreateAsync函数中使用此代码,而且还希望在Create函数中使用此代码。因此,您应该考虑为上述代码使用自己的函数(例如,称为CreateTokenInternal)。 在这里,您可以找到包括refresh_token流(但未设置refresh_token的到期时间)在内的不同流的实现。
这是GitHub上IAuthenticationTokenProvider的一个示例实现(设置了refresh_token的到期时间)
很抱歉,除了OAuth规范和Microsoft API文档之外,我无法提供更多其他材料。我会在此处发布链接,但我的声誉不允许我发布超过2个链接…。
我希望这可以帮助其他人在尝试实现OAuth2.0时的空闲时间,而OAuth2.0的refresh_token过期时间与access_token过期时间不同。我无法在网络上找到示例实现(除了上面链接的thinktecture之一),这花了我几个小时的研究才对我有用。
新信息:就我而言,我有两种不同的接收令牌的可能性。一种是接收有效的access_token。在这里,我必须发送一个带有String主体的POST调用,格式为application / x-www-form-urlencode,并带有以下数据
client_id=YOURCLIENTID&grant_type=password&username=YOURUSERNAME&password=YOURPASSWORD
其次是如果access_token不再有效,我们可以尝试通过发送POST调用来尝试refresh_token,该调用的字符串格式application/x-www- form- urlencoded为以下数据grant_type=refresh_token&client_id=YOURCLIENTID&refresh_token=YOURREFRESHTOKENGUID
application/x-www- form- urlencoded
grant_type=refresh_token&client_id=YOURCLIENTID&refresh_token=YOURREFRESHTOKENGUID