【问题标题】:Multiple Active Directory look-ups in MVC3 applicationMVC3 应用程序中的多个 Active Directory 查找
【发布时间】:2011-02-23 22:31:37
【问题描述】:

我的 MVC 应用程序允许一部分用户在表中插入/编辑记录,并且由于我使用的是 Windows 身份验证,因此我“免费”获得了他们的 samaccountnames,并且可以将它们插入到“上次更新者”字段中提到的记录。

我的应用程序中最重要(也是最常用)的视图之一将显示每页 50-100 条记录的列表,但我不想显示它们的 samaccountnames。我希望从 Active Directory 中获得更易于使用的显示名称。

我在这里看到了几篇建议将 AD 链接到 SQL 的帖子,但这需要在 SQL 服务器上安装组件,而我不想这样做。相反,我正在考虑创建以下接口和派生类:

public interface IUserInformationStore
{
  UserInformation FindBySamAccountName(string samAccountName)
}

public class ActiveDirectoryStore
{
  HashSet<UserInformation> _cache;

  public UserInformation FindBySamAccountName(string samAccountName)
  {
    // Look for samaccountname in _cache and if not found
    // retrieve information from AD with DirectorySearcher.
    // Store information in _cache and return correct user.
}

我现在的问题是如何访问这些信息。我正在考虑使用 Ninject 的 ToSingleton,但我怀疑这可能是“每个 Worker 进程的单例”。所以也许缓存会是一个更好的地方。但是访问对象的最佳方式是什么?具有静态属性的静态类,检查它是否已经在缓存中,否则初始化它,然后返回对象?

或者有没有更好的方法来解决这个问题?

【问题讨论】:

  • 当您说“每个 Worker 进程单例”时,您的意思是要在多个 Web 应用程序之间共享此信息缓存吗?
  • 看到你提供的代码sn-p,知道你使用了Ninject,我的第一反应就是使用singleton特性。但是,我问这个问题只是为了澄清信息需要走多远(跨请求?跨应用程序?跨服务器?)。
  • 这个特定的缓存只会在单个 Web 应用程序中使用,但我不确定 ninject 单例是每个应用程序单数还是 asp.net 从线程池中获取的每个线程单数。跨度>

标签: c# asp.net-mvc active-directory directoryservices


【解决方案1】:

我最终尝试了两种解决方案:

1

kernel.Bind<IUserRepository>().To<ActiveDirectoryUserRepository>().InSingletonScope().WithConstructorArgument("rootPath", "LDAP://dc=tessdata,dc=no");

public static MvcHtmlString GetDisplayNameSingleton(this HtmlHelper htmlHelper, string samAccountName)
{
  var userRepository = DependencyResolver.Current.GetService<IUserRepository>();
  return new MvcHtmlString(userRepository != null ? userRepository.FindByUsername(samAccountName).DisplayName : "Ukjent");
}

2

kernel.Bind<IUserRepository>().To<ActiveDirectoryUserRepository>().WithConstructorArgument("rootPath", "LDAP://dc=tessdata,dc=no");

public static MvcHtmlString GetDisplayName(this HtmlHelper htmlHelper, string samAccountName)
{
  if (HttpRuntime.Cache["UserRepository"] == null)
  {
    var newUserRepository = DependencyResolver.Current.GetService<IUserRepository>();
    HttpRuntime.Cache.Add("UserRepository", newUserRepository, null, DateTime.MaxValue,
                                  TimeSpan.FromMinutes(20), CacheItemPriority.Default, null);
  }
  var userRepository = HttpRuntime.Cache["UserRepository"] as IUserRepository;
  return new MvcHtmlString(userRepository != null ? userRepository.FindByUsername(samAccountName).DisplayName : "Ukjent");
}

第二种方法明显更快,尤其是在缓存存储库时第一次调用之后。您也可以更好地控制缓存。第一种方法将一直保留在内存中,直到应用程序重新启动。

不过,我不确定这两种情况下的最佳做法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多