我正在从接收googleIdToken(GoogleAuth)的端点在ASP.NET中生成访问令牌。访问令牌已成功生成并且可以正常工作,我可以使用它毫无问题地向我的API发出请求。当我尝试从同一端点生成刷新令牌时,就会出现问题。我可以看到刷新令牌已添加到数据库中,但是当我尝试使用刷新令牌获取新的访问令牌时,它将返回“ invalid_grant”。
调试我发现检索刷新令牌后,我的 ApplicationOAuthProvider 中的 GrantRefreshToken 方法未执行。
这是我创建访问令牌和刷新令牌的方法:
我的端点:
[System.Web.Http.HttpPost]
[System.Web.Http.AllowAnonymous]
public async Task<IHttpActionResult> GenerateEHSTokenFromGAuth(ExternalSignInRequest request){
//gets user info from google
var tokenInfo = await GoogleJsonWebSignature.ValidateAsync(request.TokenId);
//Some logic to match google user to my users table.
// Generate AuthTicket
var oAuthIdentity = await user.GenerateUserIdentityAsync(_userManager, OAuthDefaults.AuthenticationType);
var formData = GetRequestInfo(request);
var ticket = await _authService.CreateAuthTicket(oAuthIdentity, formData);
var token = _authService.CreateToken(ticket);
var cookiesIdentity = await user.GenerateUserIdentityAsync(_userManager, CookieAuthenticationDefaults.AuthenticationType);
AuthenticationManager.SignIn(cookiesIdentity);
//Create refresh token
Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext context =
new Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext(
HttpContext.Current.GetOwinContext(),
Startup.OAuthOptions.AccessTokenFormat, ticket);
await Startup.OAuthOptions.RefreshTokenProvider.CreateAsync(context);
var refreshToken = context.Token;
var accessTokenExpiration = ((DateTimeOffset)ticket.Properties.ExpiresUtc).Subtract((DateTimeOffset)ticket.Properties.IssuedUtc).TotalSeconds;
ticket.Properties.Dictionary.Add("refresh_token", refreshToken);
ticket.Properties.Dictionary.Add("access_token", token);
ticket.Properties.Dictionary.Add("expires_in", accessTokenExpiration.ToString());
ticket.Properties.Dictionary.Add("token_type", "bearer");
context.SerializeTicket();
return Ok(ticket.Properties.Dictionary);
}
RefreshTokenProvider:
public async Task CreateAsync(AuthenticationTokenCreateContext context)
{
var username = context.Ticket.Identity.Name;
var unit = (IUnitOfWork)DependencyResolver.Current.GetService(typeof(IUnitOfWork));
var refreshTokenLifeTime = ConfigurationManager.AppSettings["RefreshLifetimeMinutes"];
var aspnetRefreshTokenId = Guid.NewGuid();
var data = await context.Request.ReadFormAsync();
var userName = context.Ticket.Identity.Name;
var token = new AspNetRefreshToken()
{
AspNetRefreshTokenId = aspnetRefreshTokenId,
UserName = userName,
IssuedTime = DateTime.UtcNow,
DeviceSource = GetDeviceSource(),
ExpiredTime = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenLifeTime))
};
token.ProtectedTicket = context.SerializeTicket();
//Remove old refresh tokens
var tokensToRemove = unit.AspNetRefreshTokenRepository.Get()
.Where(x => (x.DeviceSource == deviceSource || x.DeviceSource == null) && x.UserName == userName || x.ExpiredTime < DateTime.UtcNow);
foreach (var tokenToRemove in tokensToRemove)
unit.AspNetRefreshTokenRepository.Remove(tokenToRemove.AspNetRefreshTokenId);
unit.AspNetRefreshTokenRepository.Add(token);
context.SetToken(aspnetRefreshTokenId.ToString());
unit.Save();
}
这是当我尝试使用刷新令牌获取访问令牌时调用的方法。我可以看到令牌是从数据库中检索到的,但是执行此方法后,执行结束,并且我收到invalid_grant消息。
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
var unit = (IUnitOfWork)DependencyResolver.Current.GetService(typeof(IUnitOfWork));
var data = await context.Request.ReadFormAsync();
var deviceSource = data.Get("device_source");
Guid tokenId = Guid.Empty;
var validGuid = Guid.TryParse(context.Token, out tokenId);
if (!validGuid)
return;
var token = unit.AspNetRefreshTokenRepository.Get()
.FirstOrDefault(x => x.AspNetRefreshTokenId == tokenId && x.DeviceSource == deviceSource);
if (token == null)
return;
context.DeserializeTicket(token.ProtectedTicket);
unit.AspNetRefreshTokenRepository.Remove(new Guid(context.Token));
unit.Save();
}
答案 0 :(得分:0)
好吧,问题是我在使用错误的TokenFomat创建上下文。如果您需要为刷新令牌创建上下文,则需要为该上下文提供RefreshTokenFormat。
所以不是
Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext context =
new Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext(
HttpContext.Current.GetOwinContext(),
Startup.OAuthOptions.AccessTokenFormat, ticket);
要做:
Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext context =
new Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext(
HttpContext.Current.GetOwinContext(),
Startup.OAuthOptions.RefreshTokenFormat, ticket);
这将执行 GrantRefreshToken ,您可以在其中创建新的访问令牌。