asp.net – 如何使用外部登录提供程序创建刷新令牌?
我已经通过网络搜索,找不到我的问题的解决方案.我在我的应用程序中执行OAuth.我正在使用ASP .NET Web API 2和Owin.这种情况是,一旦用户向令牌终端请求,他或她将收到一个访问令牌以及刷新令牌,以生成一个新的访问令牌.我有一个类帮助我生成刷新令牌.就这个 :
public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider { private static ConcurrentDictionary<string,AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string,AuthenticationTicket>(); public async Task CreateAsync(AuthenticationTokenCreateContext context) { var refreshTokenId = Guid.NewGuid().ToString("n"); using (AuthRepository _repo = new AuthRepository()) { var refreshTokenLifeTime = context.OwinContext.Get<string> ("as:clientRefreshTokenLifeTime"); var token = new RefreshToken() { Id = Helper.GetHash(refreshTokenId),ClientId = clientid,Subject = context.Ticket.Identity.Name,IssuedUtc = DateTime.UtcNow,ExpiresUtc = DateTime.UtcNow.AddMinutes(15) }; context.Ticket.Properties.IssuedUtc = token.IssuedUtc; context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc; token.ProtectedTicket = context.SerializeTicket(); 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) { string hashedTokenId = Helper.GetHash(context.Token); using (AuthRepository _repo = new AuthRepository()) { var refreshToken = await _repo.FindRefreshToken(hashedTokenId); if (refreshToken != null ) { //Get protectedTicket from refreshToken class context.DeserializeTicket(refreshToken.ProtectedTicket); // one refresh token per user and client var result = await _repo.RemoveRefreshToken(hashedTokenId); } } } public void Create(AuthenticationTokenCreateContext context) { throw new NotImplementedException(); } public void Receive(AuthenticationTokenReceiveContext context) { throw new NotImplementedException(); } } 现在我允许我的用户通过Facebook注册.一旦用户注册Facebook,我会生成一个访问令牌并将其交给他.我还应该生成刷新令牌吗? Onething来到我的脑海里,是生成一个长的访问令牌,如一天,那么这个用户必须再次使用Facebook登录.但是,如果我不想这样做,我可以给客户端一个刷新令牌,他可以使用它刷新生成的访问令牌,并获得一个新的.当有人注册或登录Facebook或外部时,如何创建刷新令牌并将其附加到响应? 这是我的外部注册API public class AccountController : ApiController { [AllowAnonymous] [Route("RegisterExternal")] public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var accessTokenResponse = GenerateLocalAccessTokenResponse(model.UserName); return Ok(accessTokenResponse); } } //私有方法来生成访问令牌 private JObject GenerateLocalAccessTokenResponse(string userName) { var tokenExpiration = TimeSpan.FromDays(1); ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.Name,userName)); identity.AddClaim(new Claim("role","user")); var props = new AuthenticationProperties() { IssuedUtc = DateTime.UtcNow,ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration),}; var ticket = new AuthenticationTicket(identity,props); var accessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket); JObject tokenResponse = new JObject( new JProperty("userName",userName),new JProperty("access_token",accessToken),// Here is what I need new JProperty("resfresh_token",GetRefreshToken()),new JProperty("token_type","bearer"),new JProperty("refresh_token",refreshToken),new JProperty("expires_in",tokenExpiration.TotalSeconds.ToString()),new JProperty(".issued",ticket.Properties.IssuedUtc.ToString()),new JProperty(".expires",ticket.Properties.ExpiresUtc.ToString()) ); return tokenResponse; } 解决方法
我花了很多时间找到这个问题的答案.所以,我很乐意帮助你.
1)更改您的ExternalLogin方法. if (hasRegistered) { Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,OAuthDefaults.AuthenticationType); ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName); Authentication.SignIn(properties,oAuthIdentity,cookieIdentity); } 现在,实际上有必要添加refresh_token. if (hasRegistered) { Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName); // ADD THIS PART var ticket = new AuthenticationTicket(oAuthIdentity,properties); var accessToken = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket); Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext context = new Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext( Request.GetOwinContext(),Startup.OAuthOptions.AccessTokenFormat,ticket); await Startup.OAuthOptions.RefreshTokenProvider.CreateAsync(context); properties.Dictionary.Add("refresh_token",context.Token); Authentication.SignIn(properties,cookieIdentity); } 现在将生成refrehs令牌. 2)在SimpleRefreshTokenProvider CreateAsync方法中使用基本context.SerializeTicket有一个问题.
因此,您需要使用Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer来对门票进行搜索和反序列化. Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer serializer = new Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer(); token.ProtectedTicket = System.Text.Encoding.Default.GetString(serializer.Serialize(context.Ticket)); 代替: token.ProtectedTicket = context.SerializeTicket(); 而对于ReceiveAsync方法: Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer serializer = new Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer(); context.SetTicket(serializer.Deserialize(System.Text.Encoding.Default.GetBytes(refreshToken.ProtectedTicket))); 代替: context.DeserializeTicket(refreshToken.ProtectedTicket); 3)现在,您需要将refresh_token添加到ExternalLogin方法响应. public override Task AuthorizationEndpointResponse(OAuthAuthorizationEndpointResponseContext context) { var refreshToken = context.OwinContext.Authentication.AuthenticationResponseGrant.Properties.Dictionary["refresh_token"]; if (!string.IsNullOrEmpty(refreshToken)) { context.AdditionalResponseParameters.Add("refresh_token",refreshToken); } return base.AuthorizationEndpointResponse(context); } 所以..这一切!现在,在调用ExternalLogin方法后,你会得到url: 我希望这有帮助) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – DAL中的app.config和WebApplication中的web
- 在Entity Framework中使用存储过程(三):逻辑删除的实现与
- iis-7 – 经典ASP突然给我权限(401.3)错误
- 什么可以导致ASP.NET工作进程被回收?
- asp.net-mvc-3 – 如何在控制器方法的新选项卡中打开cshtml
- Fluent验证比较字段字符串格式args
- asp.net-mvc-3 – 将WebForms中的MVC3与大型现有的自定义控
- 谈谈基于SQL Server 的Exception Handling[中篇]
- asp.net-mvc – 找不到CrystalImageHandler.aspx
- asp.net-mvc – Dotnetopenauth使用自定义身份提供者单点登
- asp.net – Xamarin.Forms应用程序SQL服务器数据
- .net-4.0 – 为什么有潜在危险的请求错误甚至Val
- asp.net – Visual Studio开发服务器(2010)和NTL
- asp.net-mvc – 如何使更多MapHttpRoutes为MVC 4
- asp.net-mvc – ASP.NET MVC – Cascading Drop
- ASP.NET MVC – 将XHTML添加到验证错误消息中
- ASP.NET 2.0异步用户控件不起作用
- asp.net-mvc – ASP.NET MVC主页数据
- asp.net-mvc – 在ASP.NET身份中角色与声明的最佳
- 如何在ASP.NET中的Web应用程序之间共享用户控件?