如何在Web API 2中存储服务器端的持票人代币?
我在Web API 2中设置不记名令牌authentication,我不明白如何(或在哪里)不记名的令牌存储在服务器端。 这是相关的代码:
启动:
public partial class Startup { public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; } public static Func<UserManager<IdentityUser>> UserManagerFactory { get; set; } public static string PublicClientId { get; private set; } static Startup() { PublicClientId = "self"; UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>()); OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/Token"), Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory), AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), AllowInsecureHttp = true }; } public void ConfigureAuth(IAppBuilder app) { // Enable the application to use a cookie to store information for the signed in user app.UseCookieAuthentication(new CookieAuthenticationOptions()); // Use a cookie to temporarily store information about a user logging in with a third party login provider app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); app.UseOAuthBearerTokens(OAuthOptions); } }
WebApiConfig:
public class WebApiConfig { public static void ConfigureWebApi() { Register(GlobalConfiguration.Configuration); } public static void Register(HttpConfiguration http) { AuthUtil.ConfigureWebApiToUseOnlyBearerTokenAuthentication(http); http.Routes.MapHttpRoute("ActionApi", "api/{controller}/{action}", new {action = Actions.Default}); } }
AuthUtil:
public class AuthUtil { public static string Token(string email) { var identity = new ClaimsIdentity(Startup.OAuthOptions.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.Name, email)); var ticket = new AuthenticationTicket(identity, new AuthenticationProperties()); var currentUtc = new SystemClock().UtcNow; ticket.Properties.IssuedUtc = currentUtc; ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30)); var token = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket); return token; } public static void ConfigureWebApiToUseOnlyBearerTokenAuthentication(HttpConfiguration http) { http.SuppressDefaultHostAuthentication(); http.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); } }
的LoginController:
public class LoginController : ApiController { ... public HttpResponseMessage Post([FromBody] LoginJson loginJson) { HttpResponseMessage loginResponse; if (/* is valid login */) { var accessToken = AuthUtil.Token(loginJson.email); loginResponse = /* HTTP response including accessToken */; } else { loginResponse = /* HTTP response with error */; } return loginResponse; } }
使用上面的代码,我可以login和存储不记名的客户端在一个cookie,然后打电话给控制器标有[授权],它让我进来。
我的问题是:
-
不记名令牌在哪里/如何被存储在服务器端? 似乎这是通过OWIN电话之一,但我不知道在哪里。
-
是否有可能持有人的令牌到服务器端的数据库,以便他们可以在Web API服务器重新启动后保持原位?
-
如果#2的答案是否定的,那么即使在Web APIclosures并重新启动之后,客户端是否仍然保留其不记名令牌并重新使用? 虽然这在生产中可能很less见,但经常会在本地进行testing。
-
它们不是存储在服务器端 – 它们被发送到客户端,客户端在每次调用时都会显示它们。 他们validation,因为他们是由owin主机的保护密钥签名。 在SystemWeb宿主中,该保护密钥是web.config中的machineKey设置。
-
这是不必要的,只要owin主机使用的保护密钥在服务器重启之间不会改变。
-
只要令牌有效,客户端就可以持有令牌。
为了补充这一点,令牌可以使用CookieAuthenticationOptions的SessionStore属性持久化服务器端。 我不会主张这样做,但是如果你的代币变得过大,那就在那里。
这是一个IAuthenticationSessionStore,所以你可以实现自己的存储介质。
对于那些正在寻找如何设置web.config,这里是一个示例
<system.web> <machineKey validation="HMACSHA256" validationKey="64-hex" decryption="AES" decryptionKey="another-64-hex"/> </system.web>
您需要同时使用validationKey和decriptionkey才能使其工作。
这里是如何生成密钥https://msdn.microsoft.com/en-us/library/ms998288.aspx