如何解决如何使用Oauth2在ASP.NET Web API上刷新外部令牌
我有一个使用OAuth2流Microsoft.Owin.Security.OAuth进行身份验证的移动应用程序。
现在,我需要使用仅提供令牌和刷新令牌的外部身份验证API。但是我很难将服务与我们的Mobile API集成在一起。
我的目的是调用Mobile API的/ token,然后调用此外部身份验证API。
这就是我的启动课程的方式:
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),Provider = new ApplicationOAuthProvider(PublicClientId),AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(2),AllowInsecureHttp = true,RefreshTokenProvider = new LoginServiceRefreshTokenProvider(loginServiceURL),AccessTokenProvider = new LoginServiceAccessTokenProvider(loginServiceURL)
};
还有我的AccessTokenProvider
public override Task CreateAsync(AuthenticationTokenCreateContext context)
{
string userName = null;
string password = null;
string clientId = null;
context.Ticket.Properties.Dictionary.TryGetValue("userName",out userName);
context.Ticket.Properties.Dictionary.TryGetValue("password",out password);
context.Ticket.Properties.Dictionary.TryGetValue("as:client_id",out clientId);
var client = new RestClient(_loginServiceURL + "token");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddParameter("grant_type","password");
request.AddParameter("username",userName);
request.AddParameter("password",password);
request.AddParameter("client_id","myclientid");
request.AddParameter("client_secret","myclientsecret");
IRestResponse response = client.Execute(request);
Token token = JsonConvert.DeserializeObject<Token>(response.Content);
context.Ticket.Properties.Dictionary.Add("as:clientRefreshTokenLifeTime",token.ExpiresIn.ToString());
context.Ticket.Properties.Dictionary.Add("refresh_token",token.RefreshToken);
context.SetToken(token.AccessToken);
context.Ticket.Properties.AllowRefresh = true;
context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;
context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddSeconds(Convert.ToDouble(token.ExpiresIn));
return Task.FromResult<object>(null);
}
}
internal class Token
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
}
还有我的RefreshTokenProvider
public async Task CreateAsync(AuthenticationTokenCreateContext context)
{
var refreshTokenId = Guid.NewGuid().ToString("n");
string clientId = context.Ticket.Properties.Dictionary["as:client_id"];
string refreshTokenLifeTime = context.Ticket.Properties.Dictionary["as:clientRefreshTokenLifeTime"];
context.Ticket.Properties.AllowRefresh = true;
string refreshToken = context.Ticket.Properties.Dictionary["refresh_token"];
var token = new RefreshToken()
{
Id = refreshTokenId,ClientId = clientId,IssuedUtc = DateTime.Now,ExpiresUtc = DateTime.Now.AddSeconds(Int32.Parse(refreshTokenLifeTime)),Subject = context.Ticket.Identity.Name,ProtectedTicket = refreshToken
};
var result = await _repo.AddRefreshToken(token);
if (result)
{
context.SetToken(refreshTokenId);
}
}
// this method will be used to generate Access Token using the Refresh Token
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer serializer = new Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer();
if (context.Token != null)
{
context.SetTicket(serializer.Deserialize(System.Text.Encoding.Default.GetBytes(context.Token)));
return;
}
var refreshToken = await _repo.FindRefreshToken(context.Token);
if (refreshToken != null)
{
var client = new RestClient(_loginServiceURL + "token");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddParameter("grant_type","refresh_token");
request.AddParameter("refresh_token",refreshToken.ProtectedTicket);
request.AddParameter("client_id","myclientsecret");
IRestResponse response = client.Execute(request);
Token newToken = JsonConvert.DeserializeObject<Token>(response.Content);
context.SetTicket(serializer.Deserialize(System.Text.Encoding.Default.GetBytes(newToken.AccessToken)));
var result = await _repo.RemoveRefreshToken(context.Token);
}
}
In the other hand with grant_type refresh_token I get the error "invalid_grant"
我不确定这是否是正确的流程,但我的目的是要获取访问令牌和刷新AccessTokenProvider(当用户登录时)
并在需要时使用RefreshToken在RefreshTokenProvider中请求新令牌。
- 令牌寿命是在此第三方身份验证API中自定义的,因此我需要在首次调用中进行设置。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。