I am calling a service, and I need to pass the user\'s permanent security token with every request I make.
In order to do that, I\'ve added this method to my base
I would go for storing the security token of the user in the forms authentication cookie itself. The FormsAuthenticationTicket
class contains an UserData
property where you can include your additional information.
The value specified in the
UserData
property is included as part of the authentication ticket cookie and, like the other ticket fields, is encrypted and validated based on the forms authentication system's configuration.
Here is an article that described how you can store additional information to the forms authentication cookie.
This is a big article that explains much about storing additional data into the forms auth. cookie and how you could read it. The code is written in VB and not well formatted. You have to scroll down to the Step 4: Storing Additional User Data in the Ticket.
This thread will give you a quick answer how you could read the UserData
from the cookie.
I would go for creating a custom ValueProvider
like the one described here that will read the security token from the auth. cookie and feed to the action parameters.
If User.Identity
outlasts the Session, why not store the token as a Claim
in the Identity? Something like:
var claims = new[]
{
new Claim("access_token", string.Format("Bearer {0}", token)),
};
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
Request.GetOwinContext().Authentication.SignIn(options, identity);
You can place the users security token, IP address, and a time-stamp in a string. Encrypt the string with a symmetric algorithm such as AES and place it as a cookie. Then change your code to read from the cookie. You can validate that the ip address in the cookie matches the users ip address, this will prevent someone stealing the cookie value and replaying it. Here is the MSDN documentation on AES (Rjindael is the original name). In this scheme, the token will not expire until the cookie expires and/or your timeout is reached. I do highly recommend you put a timeout and not make it forever or persistent, it will make the scheme less secure to exclude a timeout. Also put the time-stamp at the beginning of your cookie value, because of CBC mode on these algorithms it will affect the way the encrypted string looks because of the changes in bits at the begining (Avalanche effect).
The ASP.NET membership provider also has an authentication cookie so this cookie should not expire before the membership cookie. Sessions have to expire on a timeout because there is no guarantee that the user is still there as HTTP is stateless whereas the cookie is under the control of the user and is passed every single time a request is made.
getUsr function
protected UserData getUsr()
{
try
{
UserData usr = new UserData();
string token = Request.Cookies["secToken"].Value;
// implement RijndaelManaged encryption/decryption scheme
// this can also be serialized as an object to make cleaner
var tokenValues = Decrypt(token).Split(',');
// The timeout expired
if (DateTime.Now > DateTime.Parse(tokenValues[1]))
{
throw new Exception("Timeout");
}
// someone stole this cookie or is on a different internet connection
if (tokenValues[0] != System.Web.HttpContext.Current.Request.UserHostAddress)
{
throw new Exception("Invalid IP");
}
// You're ok everything checks out
usr.SecurityToken = tokenValues[3].ToString();
MembershipUser mvcUser = Membership.GetUser(HttpContext.Current.User.Identity.Name);
usr.Id = (int)mvcUser.ProviderUserKey;
return usr;
}
catch (Exception ex)
{
log.Debug("Could not create usr object", ex);
throw new Exception("Could not authenticate");
}
}
Maybe what I am saying is very stupid, but in the past I had a similar problem and I solved it by simply setting the session expiration time greater than than the logged in expiration time. Whenerver, you are able to enter the web siteb with the security token you refresh the session data, so for sure they will last for the whole time the user is logged in. The fact that the session has a greater duration cannot cause problems, since just a logged in user can use that data, and when a new user logs in the old session entry is replaced.