Reputation: 13531
I have an ASP.NET MVC application that consumes various operations of a Web API. It uses ACS for security and so users have to log on first with their Microsoft account before they can do anything.
One of these web API operations is getting the list of permissions for the currently logged on user. This call is done for every page request, as we need this information to correctly display, disable or hide UI elements. This works fine.
As permissions don't change often, I would like to cache them so that the call to the web API is only done the first time.
Normally session is the way to keep user-specific data in memory, but I want to remain stateless/sessionless.
Would it be technically OK to use the application cache, in which I store the permissions with a key that includes the user's unique identification? Are there any risks/disadvantages of doing it like this?
[I also would like to keep the option open to later replace it with (Azure) distributed caching later, if needed, but for now the solution should be a simple built in one which is free :)]
EDIT: the cache is meant to live as long as the user is working, so it's mostly short-term cache.
Upvotes: 1
Views: 1412
Reputation: 2924
Application cache seems not to be not a good option. First of all, your application process may be restarted and then all the data will be lost. On other hand, if the application is running for a long time and you have a significant number of users, it will cause significant growth process of memory size.
I'd suggest you to use encrypted cookie. Upon successful login you set the cookie with his id / permission and upon logout remove it. This way you make user login really persistent and independent on session / server state and also free your server from unnecessary storage. Encryption protects against the possibility to abuse the cookie by its reverse engineering and receive another user's permissions.
See the sample code below:
// on login successful
string EncryptedUserId = EncriptCookie(UserId, Permissions);
HttpCookie LoginCookie = new HttpCookie("yoursitename");
LoginCookie.Values.Add("userinfo", EncryptedUserId);
LoginCookie.Expires = DateTime.Now.AddYears(10);
HttpContext.Current.Response.AppendCookie(LoginCookie);
public static void Logout()
{
HttpCookie LoginCookie = new HttpCookie("yoursitename");
LoginCookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.AppendCookie(LoginCookie);
}
private static string EncriptCookie(int UserId, string Permissions)
{
string CookieString = UserId.ToString() + "#" + Permissions);
DESCryptoServiceProvider Crypt = new DESCryptoServiceProvider();
Crypt.Key = ASCIIEncoding.ASCII.GetBytes("MYSECRET");
Crypt.IV = ASCIIEncoding.ASCII.GetBytes("MYSECRET");
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, Crypt.CreateEncryptor(), CryptoStreamMode.Write);
byte[] EncBytes = ASCIIEncoding.ASCII.GetBytes(CookieString);
cs.Write(EncBytes, 0, EncBytes.Length);
cs.FlushFinalBlock();
string EncryptedCookie = Convert.ToBase64String(ms.ToArray());
return EncryptedCookie;
}
Upvotes: 1