我使用ASP.NET MVC4構建了一個簡單的Intranet應用程序,該應用程序允許網絡內的用戶查看一些資源。應用程序主要在ExtJS和WebAPI控制器中構建。
我的授權基於Active Directory。針對特定用戶的WebAPI存儲變量
調試我的代碼我注意到我正在做多次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
但會話是按用戶和應用程序緩存。
什麼是每個用戶存儲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分鐘重新查詢(緩存有超時)。
我該如何讓這更容易/更好?還有其他方法可以做到這一點嗎?
您可以使用'Dictionary'來永遠緩存它,應該是足夠的數據結構。或者你可以使用'System.Runtime.Caching'來緩存TTL值。 –
Seph
@Seph - 我想保持30分鐘,因爲有時AD對象可以改變(例如特權),我想在一段時間後加載這些更新。會話是每個用戶,但與詞典<字符串,員工>我可以存儲每個員工緩存,因爲他們將有獨特的指導。因此,擁有該字典的緩存對象可以只刷新特定的員工嗎?我可以爲整個Cached對象設置過期期限,但是我可以爲該Dictionary元素執行相同的操作嗎? – Misiu
,因爲@oeoren會使用'System.Runtime.Caching'進一步解釋。 – Seph