问题
We've developed a REST API using ASP.NET WebAPI 2 & secured it using ASP.NET Identity. The client required that their token be set to a long expiration time, as they store the access token in their database.
During testing, they requested that we reduce the length of the token, as their database can only handle strings up to 250 characters. Our implementation is pretty "vanilla". Below are the options we're currently setting for the bearer token:
OAuthOptions = new OAuthAuthorizationServerOptions {
TokenEndpointPath = new PathString("/oauth/2/token"),
Provider = new ApplicationOAuth2Provider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1000000),
AllowInsecureHttp = true
};
How would we go about shorting the token to the 250 character limit? I've noticed some properties relating to setting custom access token formatters etc, but am unsure on how to implement these & what the restrictions and\or pitfalls are.
Any assistance would be greatly appreciated.
回答1:
The answer is Yes.
Since client just sends the same token string back to server, you can send a hash value of the token.
What I do is using a GUID to represent the token, which is only 32 chars. And store the mapping information (GUID => token) on the server side. When user tries to authenticate by the GUID, you can read the REALLY token from where you stores it, then deserialize the ticket.
Here is the sample code, the core is to override OnCreate/OnReceive method of OAuthAuthorizationServerOptions class. You may also want to override OnCreateAsync and OnReceiveAsync.
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenProvider = new AuthenticationTokenProvider
{
OnCreate = (context) =>
{
var token = context.SerializeTicket();
var guid = Guid.NewGuid().ToString("N");
// You need to implement your own logical here, for example, store the mapping (guid => token) into database
RedisServer.SetValue(guid, token, TimeSpan.FromDays(Consts.AccessTokenExpireDays));
context.SetToken(guid);
},
OnReceive = (context) =>
{
var token = RedisServer.GetValue(context.Token);
context.DeserializeTicket(token);
}
},
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(Consts.AccessTokenExpireDays),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true,
};
回答2:
I would start by reducing the number of claims contained within the token to a bare minimum.
And 250 characters is way too short to represent any kind of encrypted data structure such as an authentication token. The client could change to varbinary but since they are messing with the schema, they might as well increase the size.
Run some tests to see what your local maximums are, and add 10%.
来源:https://stackoverflow.com/questions/34067421/shorten-access-token-returned-by-owin-in-asp-net-webapi-2