我使用ASP.NET MVC4构建了一个简单的Intranet应用程序,允许网络内的用户查看某些资源。应用程序主要在ExtJS和WebAPI控制器中构建 我的授权基于Active Directory。
调试我的代码我注意到我多次进行AD调用。 这是我的AD助手类:
public class AD
{
public static string CurrentUser = "";
public static string GetCurrentUserLogin()
{
return HttpContext.Current.User.Identity.Name.Split('\\')[1];
}
public static Employee GetCurrentUser()
{
var login = CurrentUser == "" ? GetCurrentUserLogin() : CurrentUser ;
return GetUser(login);
}
public static Employee GetCurrentUser(string login)
{
return GetUser(login);
}
public static Employee GetUser(Guid guid)
{
using (var entry = new DirectoryEntry("LDAP://wawa.firma.pl/OU=IT,DC=wawa,DC=firma,DC=pl", @"AD_client", "xyzabc"))
{
using (var searcher = new DirectorySearcher(entry))
{
byte[] bytes = guid.ToByteArray();
var sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.Append(string.Format(@"\{0}", b.ToString("X2")));
}
searcher.Filter = String.Format("(&(objectClass=User)(objectCategory=Person)(objectguid={0}))", sb);
searcher.PropertiesToLoad.Add("description");
searcher.PropertiesToLoad.Add("objectguid");
searcher.PropertiesToLoad.Add("SN");
searcher.PropertiesToLoad.Add("givenName");
searcher.PropertiesToLoad.Add("name");
searcher.PropertiesToLoad.Add("manager");
searcher.PropertiesToLoad.Add("mail");
searcher.PropertiesToLoad.Add("sAMAccountName");
searcher.PropertiesToLoad.Add("telephoneNumber");
searcher.PropertiesToLoad.Add("directReports");
searcher.SizeLimit = 1;
searcher.SearchScope = SearchScope.Subtree;
try
{
SearchResult result = searcher.FindOne();
if (result == null) return null;
var emp = ParseSearchResult(result);
emp.fullAccess = true;
return emp;
}
catch (Exception)
{
return null;
}
}
}
}
}
这样可以正常工作,但每次我必须获得当前用户ID并且我这样打电话:
var user_id = AD.GetCurrentUser().Id;
我的问题是,每当我为存储在AD中的用户请求某些属性时,我必须执行新的AD调用。 理想情况下,我想做一次简单的调用(对于当前用户)并存储它,然后每次我需要的东西我都会从本地对象中获取它。
我在WebAPI控制器中阅读了一些关于会话的文章,例如:http://stick2basic.wordpress.com/2013/04/18/how-to-access-session-in-web-api-controller-in-mvc4/,但我发现使用缓存的例子:https://github.com/filipw/AspNetWebApi-OutputCache
但Session是按用户和每个应用程序缓存。
每个用户存储ActiveDirectory结果的最佳方法是什么?我应该如何修改我的AD类来保存这些变量。
最简单的方法是将结果存储在会话中:
public static Employee GetUser(Guid guid)
{
var e = HttpContext.Current.Session[guid.ToString()] as Employee;
if (e == null)
{
//get user from AD
//store in session
}
return e;
}
这样我只能查询一次AD,但是我无法每隔n分钟重新查询一次(缓存有超时)。
如何让这更轻松/更好?还有其他方法吗?