0

我使用 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

但是会话是每个用户和每个应用程序的缓存。

为每个用户存储 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 分钟重新查询一次(缓存有超时)。

我怎样才能使这更容易/更好?还有其他方法可以做到这一点吗?

4

1 回答 1

0

你需要一些内存缓存。看看:MemoryCache 类

将 DirectoryEntry 对象以路径作为键存储在缓存中。

于 2013-07-09T10:09:50.307 回答