前向域上的LDAP

时间:2016-08-09 13:49:00

标签: c# asp.net-mvc ldap

我正在开发一个允许用户使用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知道我不知道的事情。

1 个答案:

答案 0 :(得分:0)

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

我添加了以下行

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

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

相关问题