WebAPI存储特定用户的变量

时间:2013-07-09 07:44:39

标签: c# .net asp.net-mvc-4 asp.net-web-api

我使用ASP.NET MVC4构建了一个简单的Intranet应用程序,允许网络内的用户查看某些资源。应用程序主要在ExtJS和WebAPI控制器中构建 我的授权基于Ac​​tive 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分钟重新查询一次(缓存有超时)。

如何让这更轻松/更好?还有其他方法吗?

1 个答案:

答案 0 :(得分:0)

您需要一些内存缓存。看看:MemoryCache Class

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