我有一个ASP.NET MVC应用程序,它使用Web API的各种操作。它使用ACS进行安全保护,因此用户必须首先使用其Microsoft帐户登录才能执行任何操作。
其中一个Web API操作是获取当前登录用户的权限列表。此调用是针对每个页面请求完成的,因为我们需要此信息来正确显示,禁用或隐藏UI元素。这很好。
由于权限不会经常更改,我希望将其缓存,以便只在第一次调用Web API。
通常会话是将用户特定数据保存在内存中的方法,但我希望保持无状态/无会话。
使用应用程序缓存在技术上是否可行?我在其中使用包含用户唯一标识的密钥存储权限?这样做是否有任何风险/劣势?
[我还希望保留选项以便以后稍后用(Azure)分布式缓存替换它,如果需要的话,但是现在解决方案应该是一个简单的内置免费的方式:)]
编辑:只要用户正常工作,缓存就会存在,因此它主要是短期缓存。
答案 0 :(得分:1)
应用程序缓存似乎不是一个好选择。首先,您的应用程序进程可能会重新启动,然后所有数据都将丢失。另一方面,如果应用程序运行很长时间并且您拥有大量用户,则会导致内存大小的显着增长过程。
我建议你使用加密的cookie。成功登录后,您可以使用其ID /权限设置cookie,并在注销时将其删除。这样,您可以使用户登录真正持久且独立于会话/服务器状态,并使您的服务器免于不必要的存储。加密可以防止通过逆向工程滥用cookie并获得其他用户的权限。
请参阅下面的示例代码:
// 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;
}