1

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.

2
  • How did you solve above case? Any help would be appreciated Commented Aug 7, 2020 at 13:38
  • We rewrote the UI with Angular. And now we simply hold the information it in memory. Commented Aug 10, 2020 at 6:07

1 Answer 1

1

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;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer! Are cookies not limited in size? When is application process restarted? Is it when appdomain is restarted? That does not happen a lot I guess? Also, memory size: if I use sliding options, is that still a problem? Is caching not automatically removing contents in case of memory issues?
1. Maximum cookie size is 4093 bytes. If you need to store much user-specific data you can consider localStorage. 2. Application process may be restarted because a number of reasons. For example, if you make some change and upload a newer dll to the bin derectory. 3. Server cache not deals with Application object, it was developed for the completely different purpose. 4. If you found my answer acceptable, please don't forget to mark it as accepted :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.