【问题标题】:How to pass a UserPrincipal with PrincipalContext inside ASP.NET MVC如何在 ASP.NET MVC 中使用 PrincipalContext 传递 UserPrincipal
【发布时间】:2014-01-08 16:23:11
【问题描述】:

我有以下代码可以连接到我们的广告:-

List<DomainContext> results = new List<DomainContext>();
string ADServerName = System.Web.Configuration.WebConfigurationManager.AppSettings["ADServerName"];

using (var context = new PrincipalContext(ContextType.Domain, ADServerName))
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{

以上在我们的开发机器上工作,因为 AD 和 asp.net mvc 在同一台机器上。目前我需要连接到我们在不同机器上的登台广告。所以我需要将 AD 服务帐户(用户名和密码)传递给PrincipalContext。任何人都可以建议吗?我在网上看到我需要使用UserPrincipal如下:-

public UserPrincipal(
    PrincipalContext context,
    string samAccountName,
    string password,
    bool enabled
)

但我不确定如何相应地修改我的代码?

谢谢

编辑 我尝试这样做以仅显示在其杰出帐户中具有 brancjA 或 brachB 的用户:-

public List<DomainContext> GetADUsers(string term=null)
        {
            string[] types = new string[] { "BranchA", "BranchB" };
            List<DomainContext> results = new List<DomainContext>();
            string ADServerName = System.Web.Configuration.WebConfigurationManager.AppSettings["ADServerName"];
            using (var context = new PrincipalContext(ContextType.Domain, ADServerName, "username", "password"))
            using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
            {
                var searchResults = searcher.FindAll();



                foreach (Principal p in searchResults)
                {
                   if ((term == null || p.SamAccountName.ToString().ToUpper().StartsWith(term.ToUpper())) && (types.Contains(p.DistinguishedName)))

但结果是没有用户返回。你能建议吗?

【问题讨论】:

    标签: .net asp.net-mvc asp.net-mvc-4 active-directory


    【解决方案1】:

    您是在谈论创建 PrincipalContext 并在此过程中提供特定凭据(用户名 + 密码)吗?

    查看fabolous MSDN documentation on PrincipalContext - 任何人均可免费使用 - 使用它!

    如您所见,PrincipalContext 有几个重载的构造函数以允许各种场景:

    您可能想使用this constructor here

    public PrincipalContext(
        ContextType contextType,
        string name,
        string userName,
        string password
    )
    

    这允许您传入用户名和密码以用于此上下文下的所有 AD 操作。

    更新:关于仅返回“普通”用户(并忽略“服务帐户”)的后续问题 - 当您使用 PrincipalSearcher 时,您可以定义一个“查询- by-example”委托人进行搜索:

    // create your domain context
    using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
    {
       // define a "query-by-example" principal - here, we search for a UserPrincipal 
       // and with the first name (GivenName) of "Bruce" and a last name (Surname) of "Miller"
       UserPrincipal qbeUser = new UserPrincipal(ctx);
       qbeUser.GivenName = "Bruce";
       qbeUser.Surname = "Miller";
    
       // create your principal searcher passing in the QBE principal    
       PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
    
       // find all matches
       foreach(var found in srch.FindAll())
       {
           // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....          
       }
    }
    

    当然,根据您的需要,您可能希望在您创建的“示例查询”用户主体上指定其他属性:

    • DisplayName(通常:名字 + 空格 + 姓氏)
    • SAM Account Name - 您的 Windows/AD 帐户名称
    • User Principal Name - 您的“username@yourcompany.com”样式名称

    您可以在UserPrincipal 上指定任何属性,并将它们用作PrincipalSearcher 的“示例查询”。所以真的 - 你只需要找到正确的方法来表达区分“普通”用户和“服务帐户”的标准在你的 PrincipalSearcher 中,你应该能够做到这一点

    更新 #2: 我的意思是这样的:

    // create list to hold results
    List<Principal> allNormalUsers = new List<Principal>();            
    
    // first, search OU=BranchA
    using (var context = new PrincipalContext(ContextType.Domain, ADServerName, "OU=BranchA,OU=Users", "username", "password"))
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        allNormalUsers.AddRange(searcher.FindAll());
    }
    
    // after that, search OU=BranchB
    using (var context = new PrincipalContext(ContextType.Domain, ADServerName, "OU=BranchB,OU=Users", "username", "password"))
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        allNormalUsers.AddRange(searcher.FindAll());
    }
    
    // and now your "allNormalUsers" should contain all "normal" users from OU=BranchA 
    // and from OU=BranchB
    

    【讨论】:

    • 我试过这个“使用 (var context = new PrincipalContext(ContextType.Domain, ADServerName, "username", "password"))"。但这已经返回了所有用户,甚至是服务帐户。那么有没有办法过滤用户列表,只检索实际用户?
    • @JohnJohn:当然——区分“普通”用户和“服务帐户”的标准是什么?
    • 他们的专有名称中包含诸如“OU=BranchA,OU=Users”之类的内容。
    • @JohnJohn:“普通”用户是否都在一个特定的“容器”(OU)中,而服务帐户在另一个容器中? PrincipalContext 还有另一个重载的构造函数,它允许您定义在哪个 container 中搜索这些对象,例如如果服务帐户位于其他地方,您只能在 OU=Users(及其所有子容器)中搜索
    • 我咨询了我们的系统管理员,他提到所有用户都应该有 OU=BranchA 或 OU=BranchB 。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多