面向前的域上的LDAP

本文关键字:LDAP 面向前 | 更新日期: 2023-09-27 18:01:24

我正在开发一款允许用户使用AD登录的应用程序,我使用的代码与我们在受保护的intranet中使用的代码基本相同,但这次服务器是面向前向的(或暴露在互联网上(。我的问题是,当我使用无效密码登录时,它显然会识别出这一点,然而,当我从LDAP连接获取信息(如组名(时,它会说服务器不存在。下面是我的代码和堆栈跟踪错误,这些事情在部署时很难弄清楚。。。

控制器

public ActionResult Login(LoginModel model, string returnUrl)
{
    string logon_user = model.UserName.ToString();
    string logon_password = model.Password.ToString();
    ConnHelper connhelper = new ConnHelper();
    string encryptedTicket = null;
    String adPath = "LDAP://dc1.servername.local/DC=servername,DC=local"; //Path to the LDAP directory server
    ADAuthorize adAuth = new  ADAuthorize(adPath);
    FormsAuthenticationTicket authTicket = null;
    try
    {
        if (true == adAuth.IsAuthenticated("dc1.servername.local", logon_user, logon_password))
        {
            string groups = adAuth.GetGroups();
            Account acc = new Account();
            acc.windows_id = logon_user;
            acc.password = logon_password;
            acc.igers_id = connhelper.GetiGersID(acc.windows_id);
            acc.email_address = acc.windows_id.ToString() + "@domain.com";
            acc.region = connhelper.IsNull(connhelper.GetRegionManager(acc.igers_id));
            acc.home_store_region = connhelper.IsNull(connhelper.GetHomeStoreRegion(acc.igers_id));
            acc.store_group = connhelper.IsNull(connhelper.GetStoreGroup(acc.igers_id));
            acc.home_store = connhelper.IsNull(connhelper.GetStore(acc.igers_id));
            acc.arr = connhelper.GetStores(acc.igers_id);
            //acc.home_store_phone = misc.IsNull(misc.GetHomeStorePhoneNumber("hzs"), "");
            acc.home_store_phone = connhelper.IsNull(connhelper.GetHomeStorePhoneNumber(acc.igers_id), "");
            acc.full_name = connhelper.IsNull(connhelper.GetFullName(acc.igers_id), "");
            //ErrorLabel.Text += "windows=" + misc.GetStore(acc.igers_id);
            //ErrorLabel.Text += "windows=" + acc.igers_id.ToString();
            //Add information to the session
            Session.Add("roles", groups);
            Session.Add("Account", acc);
            // Create the authentication ticket
            authTicket =
            new FormsAuthenticationTicket(1,  // version
                acc.windows_id,
                DateTime.Now,
                DateTime.Now.AddMinutes(60),
                false, groups);
            // Now encrypt the ticket.
            encryptedTicket = FormsAuthentication.Encrypt(authTicket);
            // Create a cookie and add the encrypted ticket to the cookie as data.
            HttpCookie authCookie =
                new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
            // Add the cookie to the outgoing cookies collection. 
            Response.Cookies.Add(authCookie);
            if (FormsAuthentication.GetRedirectUrl(acc.windows_id, false).EndsWith("Logout.aspx"))
            {
                return RedirectToAction("Login", "Account");
            }
            // 
            //   Validate code this does the redirect to where you want the logged in person to go to.
            //
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
        else
        {
             ModelState.AddModelError("","Authentication failed, check username and password.");
             return View(model);
        }
    }
    catch (Exception ex)
    {
        ModelState.AddModelError("", "Error authenticating. " + ex.Message);
        return View(model);
    }
   // return View(model);
}

我认为存在问题的模型的两个部分和类的实例化:

class ADAuthorize
{
    private string _path;
    private string _filterAttribute;
    public ADAuthorize(string path)
    {
        _path = path;
    }

获取用户(这将返回一个无效的用户名/通行证消息,所以我知道它正在连接。(

public bool IsAuthenticated(string domain, string username, string pwd)
{
    string domainAndUsername = domain + @"'" + username;
    DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
    try
    {
        // Bind to the native AdsObject to force authentication. 
        Object obj = entry.NativeObject;
        DirectorySearcher search = new DirectorySearcher(entry);
        search.Filter = "(SAMAccountName=" + username + ")";
        search.PropertiesToLoad.Add("SAMAccountName");
        //search.PropertiesToLoad.Add("cn");
        SearchResult result = search.FindOne();
        if (null == result)
        {
            return false;
        }
        // Update the new path to the user in the directory
        _path = result.Path;
        _filterAttribute = (String)result.Properties["SAMAccountName"][0];
        //_filterAttribute = (String)result.Properties["cn"][0];
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message);
    }
    return true;
}

这就是它抛出错误的地方:

//Gets the Group
public string GetGroups()
{
    DirectorySearcher search = new DirectorySearcher(_path);
    search.Filter = "(SAMAccountName=" + _filterAttribute + ")";
    //search.Filter = "(cn=" + _filterAttribute + ")";
    search.PropertiesToLoad.Add("memberOf");
    StringBuilder groupNames = new StringBuilder();
    try
    {
        SearchResult result = search.FindOne();
        int propertyCount = result.Properties["memberOf"].Count;
        String dn;
        int equalsIndex, commaIndex;
        for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
        {
            dn = (String)result.Properties["memberOf"][propertyCounter];
            equalsIndex = dn.IndexOf("=", 1);
            commaIndex = dn.IndexOf(",", 1);
            if (-1 == equalsIndex)
            {
                return null;
            }
            groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
            groupNames.Append("|");
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Error obtaining group names. this is where the error is thrown " + ex.Message + ex.StackTrace.ToString());
    }
    return groupNames.ToString();
}

我的错误和堆栈跟踪读取:

指定的域不存在或无法联系。

at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) 
at System.DirectoryServices.DirectoryEntry.Bind() 
at System.DirectoryServices.DirectoryEntry.get_AdsObject() 
at System.DirectoryServices.PropertyValueCollection.PopulateList() 
at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName) 
at System.DirectoryServices.PropertyCollection.get_Item(String propertyName) 
at System.DirectoryServices.DirectorySearcher.get_SearchRoot() 
at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne) 
at System.DirectoryServices.DirectorySearcher.FindOne() 
at BoxCheckInApp.Controllers.ADAuthorize.GetGroups() 

同样,这在从IDE运行时运行良好,我认为我的问题是路径,但我对AD的了解还不够,不知道什么。

面向前的域上的LDAP

经过一番挖掘,我意识到我的问题与目录搜索器有关。

我添加了以下行

 var searchRoot = new DirectoryEntry(_path, _user, _pass);
 DirectorySearcher search = new DirectorySearcher(searchRoot);

并使提交的用户名和密码对应的ADAuthorize的_user和_pass私有变量,现在正在连接。