MVC3 应用程序中的多个 Active Directory 查找

发布于 2024-10-18 22:49:30 字数 958 浏览 1 评论 0原文

我的 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,但我怀疑这可能是“Singleton Per Worker process”。所以也许缓存会是一个更好的地方。但是访问该对象的最佳方式是什么?具有静态属性的静态类,检查它是否已经在缓存中,否则初始化它,然后返回对象?

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

My MVC application allows a subset of users to insert/edit records in a table, and since I'm using Windows authentication I get their samaccountnames "for free" and can insert these in a "Last Updated By" field in the mentioned records.

One of the most important (and frequently used) views in my application will display lists of 50-100 records per page, but I don't want to display their samaccountnames. I want their more user-friendly display names that I want to get from Active Directory.

I've seen several posts here suggesting linking AD to SQL, but that requires installing components on the SQL server which I'd rather not do. Instead, I was thinking of creating the following interface and derived class:

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.
}

My problem now is how to access this information. I was thinking of using Ninject's ToSingleton, but I suspect that might be "Singleton Per Worker process". So maybe the Cache would be a better place for it. But what would be the best way of accessing the object? Static class with static property that checks if it's in the Cache already, initializes it otherwise, and returns the object?

Or is there a completely better way of solving this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温柔少女心 2024-10-25 22:49:31

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

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");
}

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

但我不确定这两种情况的最佳实践。

I tried 2 solutions eventually:

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");
}

The second method was noticeably faster, especially after the first call when the repository was cached. You get better control over caching too. The first method will stay in memory until the application is restarted.

I'm not sure about best practice in either case though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文