流动.
我正在向请求客户端发出acess_token和refresh_token.
access_token具有短暂的生命周期,而refresh_token有很长的到期时间.
像往常一样,如果access_token到期,它将使用refresh_token请求另一个access_token.
现在,我的问题.由于我的refresh_token有很长的生命周期,看起来它失败了短命的access_token的目的.让我们说如果refresh_token被泄露,黑客仍然可以得到access_token,对吧?
我查看了google和microsoft的OAuth实现,看起来除了refresh_token之外,他们还需要提供这个额外的参数.这是client_id和client_secret.看起来它们是在API的开发者页面上登录时生成的.
现在,我如何在我的项目中实现它?我想要覆盖令牌创建并在ClientId和ClientSecret上创建令牌哈希.
我正在使用最新的web api的基本OWIN / Katana身份验证,我不打算使用像Thinktecture这样的其他授权服务器.我只想使用ASP.NET Web API 2默认提供的基本功能
Startup.OAuth.cs
public partial class Startup { static Startup() { PublicclientId = "self"; UserManagerFactory = () => new UserManager<IdentityUser>(new AppUserStore()); var tokenExpiry = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["ApiTokenExpiry"]); OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/Token"),Provider = new ApplicationOAuthProvider(PublicclientId,UserManagerFactory),AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),AccesstokenExpireTimeSpan = TimeSpan.FromMinutes(tokenExpiry),AllowInsecureHttp = true,RefreshTokenProvider = new AuthenticationTokenProvider { OnCreate = CreateRefreshToken,OnReceive = ReceiveRefreshToken,} }; } private static void CreateRefreshToken(AuthenticationTokenCreateContext context) { var tokenExpiry = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["ApiTokenExpiry"]); var refreshTokenExpiry = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["ApiRefreshTokenExpiry"]); var refreshTokenProperties = new AuthenticationProperties(context.Ticket.Properties.Dictionary) { IssuedUtc = context.Ticket.Properties.IssuedUtc,ExpiresUtc = DateTime.UtcNow.AddMinutes(tokenExpiry + refreshTokenExpiry) // add 3 minutes to the access token expiry }; var refreshTokenTicket = new AuthenticationTicket(context.Ticket.Identity,refreshTokenProperties); OAuthOptions.RefreshTokenFormat.Protect(refreshTokenTicket); context.SetToken(context.SerializeTicket()); } private static void ReceiveRefreshToken(AuthenticationTokenReceiveContext context) { context.DeserializeTicket(context.Token); } }
ApplicationOAuthProvider.cs
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider { private readonly string _publicclientId; private readonly Func<UserManager<IdentityUser>> _userManagerFactory; public ApplicationOAuthProvider(string publicclientId,Func<UserManager<IdentityUser>> userManagerFactory) { if (publicclientId == null) { throw new ArgumentNullException("publicclientId"); } if (userManagerFactory == null) { throw new ArgumentNullException("userManagerFactory"); } _publicclientId = publicclientId; _userManagerFactory = userManagerFactory; } public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { using (UserManager<IdentityUser> userManager = _userManagerFactory()) { IdentityUser user = await userManager.FindAsync(context.UserName,context.Password); if (user == null) { context.SetError("invalid_grant","The user name or password is incorrect."); return; } ClaimsIdentity oAuthIdentity = await userManager.CreateIdentityAsync(user,context.Options.AuthenticationType); ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user,CookieAuthenticationDefaults.AuthenticationType); AuthenticationProperties properties = CreateProperties(user.UserName); AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity,properties); context.Validated(ticket); context.Request.Context.Authentication.SignIn(cookiesIdentity); } } }
解决方法
>导航到https://console.developers.google.com/
>选择一个项目.如果您没有,请创建一个.
>在API’S和AUTH下的左侧栏中,选择CREDENTIALS
>您应该看到您的clientID和clientSecret.如果您没有看到这些,请单击“创建新客户端ID”并完成该操作.然后应显示您的clientID和clientSecret.
如果您仍不确定,请参阅此链接:https://developers.google.com/accounts/docs/OAuth2Login#getcredentials
它描述了如何获取clientID和clientSecret.