我正在开发一个允许用户使用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知道我不知道的事情。
答案 0 :(得分:0)
我添加了以下行
var searchRoot = new DirectoryEntry(_path, _user, _pass);
DirectorySearcher search = new DirectorySearcher(searchRoot);
并使_user和_pass私有变量ADAuthorize对应于提交的用户名和密码,现在它正在连接。