throw exception to change password in ASP.NET - asp.net

i wanna ask again. How can i resolve this problem
Eror Picture
always find error, and i won't stop. I must be try with help from you guys.
after you look my error, this is my code:
using System;
using System.Web;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.Web.SessionState;
namespace FormsAuthAd
{
public class ChangePasswordPSI
{
public bool ChangePass(HttpSessionState Session, string OldPassword, string NewUPassword)
{
string Domain = Session["domain"].ToString();
string Username = Session["username"].ToString();
try
{
string ldapPath = "LDAP://MyDomain.com";
DirectoryEntry user = new DirectoryEntry(ldapPath, Domain + "\\" + Username, OldPassword);
if (user != null)
{
DirectorySearcher search = new DirectorySearcher(user);
search.Filter = "(SAMAccountName=" + Username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if (result != null)
{
object ret = user.Invoke("ChangeUserPassword", new object[] { OldPassword, NewUPassword });
user.CommitChanges();
return true;
}
}
}
catch (Exception ex)
{
throw ex;
}
return false;
}
}
}
can somebody tell me, what should i do?
thank you

If you are using try..catch and cannot find where exactly the exception occurred, delete try and catch and execute the code again. In your example, it might happen on Invoke("ChangeUserPassword"... - as far as I see the method name should be "ChangePassword"
https://msdn.microsoft.com/en-us/library/ms180896(v=vs.80).aspx

Related

Catch exception in contact form

I'm going to create form contact in asp.net mvc 4. I have yet form in html and code in controller. And his looks like:
[HttpPost]
public ActionResult Kontakt(KontaktModel k)
{
if (ModelState.IsValid)
{
try
{
MailMessage msg = new MailMessage();
SmtpClient smtp = new SmtpClient();
MailAddress from = new MailAddress(k.Mail.ToString());
StringBuilder sb = new StringBuilder();
msg.To.Add("myemail#gmail.com");
msg.Subject = k.Temat.ToString();
msg.IsBodyHtml = false;
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
sb.Append("Nick / Imię i nazwisko: " + k.Name);
sb.Append(Environment.NewLine);
sb.Append("Typ problemu: " + k.TypProblemu);
sb.Append(Environment.NewLine);
sb.Append("Treść:");
sb.Append(Environment.NewLine);
sb.Append(k.Tresc);
msg.Body = sb.ToString();
smtp.Send(msg);
msg.Dispose();
return View("SUCCESS");
}
catch(Exception)
{
return View("Error");
}
}
return View();
}
}
But when I clicked to button app return Error.cshtml. I have a question, how I can know how exception catched? I don't know why it does not work. Any ideas?
The answer should be to get the Exception Message and put inside a ViewBag.Message and show it in the Error.cshtml view.
Error:
#ViewBag.Message
But is good to know little more about Exception and Exception Handling. If you only declare a try catch and a exception happen it will go inside the catch is the same if you do try catch(Exception) if you want to know more detail about the exception is happening you can declare a variable, example :
try{
///code
}catch(Exception e){}
and then you can watch inside the variable for more detail.
The good practice is to know what type of exception you can receive and handle, here is a link that have a good explanation Exception and Exception Handling
Example:
try
{
//code
}
catch(Exception c)
{
ViewBag.Message = c.Message
return View("ERROR");
}

Asp.net Active Directory LDAP: Trying to filter down into a group level

I have created a login page in asp.net using c# but I am having difficulty trying to only allow a certain group to have access. Right now I am accessing everyone but I can't seem to just filter the group that I need so only those person(s) can have access to my application.
Any help would be great so I can just permission this application out to that one group within Active Directory.
Here is my class that I am using to pass the groups:
public class LdapAuthentication
{
private string _path;
private string _filterAttribute;
public LdapAuthentication(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("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["cn"][0];
}
catch (Exception ex)
{
throw new Exception("Error authenticating user. " + ex.Message);
}
return true;
}
public string GetGroups()
{
DirectorySearcher search = new DirectorySearcher(_path);
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. " +
ex.Message);
}
return groupNames.ToString();
}
public bool isMember( String groupname )
{
DirectorySearcher search = new DirectorySearcher(_path);
search.Filter = "(cn=" + _filterAttribute + ")";
search.PropertiesToLoad.Add("memberOf");
try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
for (int propertyCounter = 0; propertyCounter < propertyCount;
propertyCounter++)
{
String dn = (String)result.Properties["memberOf"][propertyCounter];
// The comma in the regex is important to prevent accidental matches
if ( Regex.IsMatch( dn, #"cn="+groupname+",.*", RegexOptions.IgnoreCase))
return true;
}
}
catch (Exception ex)
{
// Some logging here probably
}
return false;
}
}
It has to be in the Get groups function but I am not sure how to pass the group I am looking for. If anyone can help that would be greatly appreciated. Thanks in advance.
Here is my button click event:
protected void btnLogin_Click(object sender, EventArgs e)
{
// Path to you LDAP directory server.
// Contact your network administrator to obtain a valid path.
string adPath = "LDAP://domain.com";
LdapAuthentication adAuth = new LdapAuthentication(adPath);
String myGroupName = "Some_Group";
try
{
if (true == adAuth.IsAuthenticated(txtDomainName.Text, txtLoginID.Text, txtPassword.Text))
{
if( adAuth.isMember( myGroupName ) )
{
// User is authenticated and a member of the group.
// Create your auth ticket, cookie, and whatnot
// Retrieve the user's groups
string groups = adAuth.GetGroups();
// Create the authetication ticket
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, // version
txtLoginID.Text,
DateTime.Now,
DateTime.Now.AddMinutes(60),
false, groups);
// Now encrypt the ticket.
string 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);
// Redirect the user to the originally requested page
//Response.Redirect(FormsAuthentication.GetRedirectUrl(txtLoginID.Text, false));
Response.Redirect("LookupEdit.aspx");
}
else
{
lblError.Text = "Authorization failed. You are not a member of the "+myGroupName+" group";
}
}
else
{
lblError.Text = "Authentication did not succeed. Check user name and password.";
}
}
catch(Exception ex)
{
lblError.Text = "Error authenticating. " + ex.Message;
}
}
OK so after your comments, here's what you should do:
Create an isMember(String) function in your LdapAuthentication class:
public boolean isMember( String groupname )
{
DirectorySearcher search = new DirectorySearcher(_path);
search.Filter = "(cn=" + _filterAttribute + ")";
search.PropertiesToLoad.Add("memberOf");
try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
for (int propertyCounter = 0; propertyCounter < propertyCount;
propertyCounter++)
{
String dn = (String)result.Properties["memberOf"][propertyCounter];
// The comma in the regex is important to prevent accidental matches
if ( Regex.IsMatch( dn, #"cn="+groupname+",.*", RegexOptions.IgnoreCase)
return true;
}
}
catch (Exception ex)
{ // Some logging here probably
}
return false;
}
Next, add this as your btnlogin_Click code:
<script runat=server>
void btnlogin_Click(Object sender, EventArgs e)
{
String adPath = "LDAP://your.domain.com"; //Enter your domain name here
LdapAuthentication adAuth = new LdapAuthentication(adPath);
String myGroupName = "auth-group-name"; //Enter your group's name (cn) here
try
{
if(true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
{
if( adAuth.isMember( myGroupName ) )
{
// User is authenticated and a member of the group.
// Create your auth ticket, cookie, and whatnot
}
else
{
errorLabel.Text = "Authorization failed. You are not a member of the "+myGroupName+" group";
}
}
else
{
errorLabel.Text = "Authentication did not succeed. Check user name and password.";
}
}
catch(Exception ex)
{
errorLabel.Text = "Error authenticating. " + ex.Message;
}
}
</script>
This should do the trick for you. Obviously you should create some code after the isMember() check to create a secure cookie that allows other pages to check the authenticated state of the user.
Good luck.
I was also having issues with this. I use pretty much the same class as you do to do the AD authentication. I was using a different way to connect to AD but was having some strange problems. I implemented a Role Provider before I changed to this code and I'm still using that Role provider to deny and grant access. This is how I basically did it. Follow this link as it will help you set up the roles.
The only thing I changed up was the "GetRolesForUser" with..
public override string[] GetRolesForUser(string username)
{
var allRoles = new List();
var ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username);
if (user != null)
{
var groups = user.GetGroups();
allRoles.AddRange(groups.Select(x => x.Name));
}
return allRoles.ToArray();
}
This way, you can deny and grant groups within the web.config.
I do it like this..
<location path="TestPage.aspx">
<system.web>
<authorization>
<allow roles="SoftwareDevelopers" />
<deny users="*" />
</authorization>
</system.web>
</location>
So I'm denying everyone access to the TestPage.aspx besides the AD group SoftwareDevelopers.
I hope this helps.
EDIT: If you are using the link that is in the comment to do this active directory, one way to get the group is using the authentication ticket that's created when you login.
if (Request.Cookies["ADAuthCookie"] != null)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
string cookiePath = ticket.CookiePath;
DateTime expiration = ticket.Expiration;
bool expired = ticket.Expired;
bool isPersistent = ticket.IsPersistent;
DateTime issueDate = ticket.IssueDate;
string name = ticket.Name;
string userData = ticket.UserData;
int version = ticket.Version;
System.Diagnostics.Debug.WriteLine(cookiePath);
System.Diagnostics.Debug.WriteLine(expiration);
System.Diagnostics.Debug.WriteLine(expired);
System.Diagnostics.Debug.WriteLine(isPersistent);
System.Diagnostics.Debug.WriteLine(issueDate);
System.Diagnostics.Debug.WriteLine(name);
System.Diagnostics.Debug.WriteLine(userData);
System.Diagnostics.Debug.WriteLine(version);
if (userData.Contains("SoftwareDevelopers"))
{
lblMessage.Text = "You're a software developer.";
}
}
You will have to decrypt the ticket to be able to read the information. I have provided how to write it to the console so you could see how it works. If you wanted to, the if statement provided above is one way you can restrict/show parts of a page.
However, I'm finding that the link in this answer on how to set up the ADRoleProvider is probably going to be your best route.
You want to check if the user is a member of the correct group, right?
Why not create a function that accepts a group name and returns boolean, like this:
public boolean isMember( String username, String groupname )
{
DirectorySearcher search = new DirectorySearcher(_path);
search.Filter = "(cn=" + username + ")";
search.PropertiesToLoad.Add("memberOf");
try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
for (int propertyCounter = 0; propertyCounter < propertyCount;
propertyCounter++)
{
String dn = (String)result.Properties["memberOf"][propertyCounter];
// The comma in the regex is important to prevent accidental matches
if ( Regex.IsMatch( dn, #"cn="+groupname+",.*", RegexOptions.IgnoreCase)
return true;
}
}
catch (Exception ex)
{ // Some logging here probably
}
return false;
}
The best way is to let LDAP do the membership iteration, by specifying the groupname in your search. However that requires the groupname to be the complete group DN (e.g. cn=mygroup,ou=groups,dc=xxx,dc=xxx) so this might not be feasible for you:
public boolean isMember( String username, String groupdn )
{
DirectorySearcher search = new DirectorySearcher(_path);
// Escaping the input strings is advisable from a security standpoint!
search.Filter = "(&(cn=" + username + ")(memberOf=" + groupdn + "))";
search.PropertiesToLoad.Add("cn");
try
{
SearchResult result = search.FindOne();
// The LDAP server has done the matching for us
if ( result != null )
return true;
}
catch (Exception ex)
{ // Some logging here probably
}
return false;
}
Good luck!

LDAP get group names

I am getting "Logon failure: unknown user name or bad password" error when I try to get the groups a user belongs to. User authentication works fine and this is what I can't understand. How can I properly authenticate a user against AD but can't get his group names?
I get user's ID and password. I have a class that deals with authentication.
if ((true == adAuth.IsAuthenticated(sDomain, sID, sPassword)))
{
string sGroups = adAuth.GetGroups();
This is the authentication class:
public class LdapAuthentication
{
string _path;
string _filterAttribute;
public LdapAuthentication(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("cn");
SearchResult result = search.FindOne();
if ((result == null)) {
return false;
}
//Update the new path to the user in the directory.
_path = result.Path;
_filterAttribute = Convert.ToString(result.Properties["cn"][0]);
}
catch (Exception ex) {
throw new Exception("Error authenticating user. " + ex.Message);
//return false;
}
return true;
}
public string GetGroups()
{
//DirectorySearcher search = new DirectorySearcher(_path);
// Use following two lines instead of the above to handle cases of authenticatin against an LDAP server other than local AD domain
DirectoryEntry deSearchRoot = new DirectoryEntry(_path);
DirectorySearcher search = new DirectorySearcher(deSearchRoot);
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 = null;
int equalsIndex = 0;
int commaIndex = 0;
int propertyCounter = 0;
for (propertyCounter = 0; propertyCounter <= propertyCount - 1; propertyCounter++) {
dn = Convert.ToString(result.Properties["memberOf"][propertyCounter]);
equalsIndex = dn.IndexOf("=", 1);
commaIndex = dn.IndexOf(",", 1);
if ((equalsIndex == -1)) {
return null;
}
groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
groupNames.Append("|");
}
} catch (Exception ex) {
throw new Exception("Error obtaining group names. " + ex.Message);
}
return groupNames.ToString();
}
IsAuthnticated passes and works fine; GetGroups() returns "Error obtaining group names" followed by "Logon failure: unknown user name or bad password" (i.e. the exception in GetGroups()).
It works fine when I run the app from VS but when I publish it (on the same server), it behaves like this.
Any ideas greatly appreciated.
Never mind; operator error. Code works fine.

How to organize Data Access Layer (DAL) in ASP.NET

I have an ASP.NET Web Forms application developed in C#.
I would like to give structure my application by separating the DAL tasks from the code behind.
I created a class in App_Code, DBUtilities that takes care of the communication with the database, in order not to have duplicated code all along the application. The class has methods to get datatables, scalar values, etc... and they accept as parameters the connection string name and the query command as string.
The problem is that I have still all the queries' commands in my code behind. Many of them are duplicated all around the pages and this cause maintanance problems.
I was wondering if it is a good practice to create a (static) class QueryRepository that contains many string properties and associate to each of them a specific query command. Everytime I want to execute the query command MyCommand I pass to the DBUtilities class the QueryRepository.MyCommand property instaed of the string. Morevoer if I need to change a query command I do it just on the QueryRepository class.
Is it a good way to organize my DAL?
For ASP.NET web forms implementing Model-View-Presenter (MVP) pattern can be one good approach to separate your logic and database queries from the UI code behind. You have to write a Presenter class that has a generic reference to a view interface and has a model in it which has database queries, logic etc. The presenter will call functions of the generic view interface in all its functions. Then you can write the actual ASP.net view. In the view you instantiates and reference this presenter and while instantiating the presenter you inject the self object i.e the ASP view itself (using "this" keyword) to the Presenter. You can design proper inheritance for your presenter classes based on your need so that they are reusabe and can be unit tested.
Addition in response to CiccioMiami's query:
Here are couple of links to start
http://www.codeproject.com/KB/aspnet/AspNet_MVP.aspx
http://wiki.asp.net/page.aspx/340/mvp-pattern/
The difference in the MVC and MVP pattern is explained here: http://www.codeproject.com/KB/architecture/DotNetMVPFramework_Part1.aspx
To add to this, for ASP.net Web form architecture, the Requests are tightly coupled with the page life cycle. You have series of page life cycle events and developers write code in each of these events. Thus the business logic becomes tightly coupled to the UI view. Over the period of time this is not a good situation for code maintainability and unit testing. Unit testing is difficult in ASP.net web forms as it is difficult to simulate the requests and page life cycle events. In MVC the requests first comes to a controller. The controller uses the model for business logic and passes the model to view. The view renders using the model data and is returned back as the response to the user. The controller has greater control on the work-flow. You can test the model, DTO transfers etc. as you could do in a standalone app. With web forms there is no controller the request directly comes to ASP.net page which is a view. There is nothing much user can do. Good that Microsoft realized this problem and we have ASP.net MVC. The MVP pattern for ASP.net webforms will solve the code separation problem to some extent. The best option is to use ASP.net MVC if not then you can use MVP with Webforms.
Long term answer: I can really recommend you read Professional Enterprise .NET
The ASP.NET website has a good example of the repository pattern which is worth looking at.
I'm no expert, but if your DAL can conform to a best-practise patterns it's more likely to be a good way for it to be organised.
I'm struggling to follow your DAL design without a concrete example, so not sure I can help there.
Few steps to follow:
It is good practice to separate the DAL, BLL code from presentation(UI) layer, however to go accordingly below steps would be helpful.
Create DTO (Data Transfer Object) or Entity
Fill the DTO/Entity from presentation layer
Pass it to a public method to your BLL layer and validate Business Logic
Then pass the DTO/Entity to DAL layer (at DAL layer, create a method which return Command, then put your CommandText, CommandType and then Set value, data type and size to all the parameters, also create execute method which get Command and return results).
Finally, execute your desired execute method ( created at DAL layer)
namespace DAL
{
public class DBAccess
{
private IDbCommand cmd = new SqlCommand();
private string strConnectionString = "";
private bool handleErrors = false;
private string strLastError = "";
public DBAccess()
{
ConnectionStringSettings objConnectionStringSettings = ConfigurationManager.ConnectionStrings["connectionString"];
strConnectionString = objConnectionStringSettings.ConnectionString;
SqlConnection cnn = new SqlConnection();
cnn.ConnectionString = strConnectionString;
cmd.Connection = cnn;
cmd.CommandType = CommandType.StoredProcedure;
}
public SqlConnection OpenSqlConnection()
{
try {
SqlConnection Conn = new SqlConnection(strConnectionString);
Conn.Open();
return Conn;
} catch (SqlException e) {
throw e;
} catch (Exception ex) {
throw ex;
}
}
public IDataReader ExecuteReader()
{
IDataReader reader = null;
try {
this.Open();
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
} catch (Exception ex) {
if (handleErrors) {
strLastError = ex.Message;
} else {
throw;
}
}
return reader;
}
public IDataReader ExecuteReader(string commandtext)
{
IDataReader reader = null;
try {
cmd.CommandText = commandtext;
reader = this.ExecuteReader();
} catch (Exception ex) {
if ((handleErrors)) {
strLastError = ex.Message;
} else {
throw;
}
}
return reader;
}
public object ExecuteScalar()
{
object obj = null;
try {
this.Open();
obj = cmd.ExecuteScalar();
this.Close();
} catch (Exception ex) {
if (handleErrors) {
strLastError = ex.Message;
} else {
throw;
}
}
return obj;
}
public object ExecuteScalar(string commandtext)
{
object obj = null;
try {
cmd.CommandText = commandtext;
obj = this.ExecuteScalar();
} catch (Exception ex) {
if ((handleErrors)) {
strLastError = ex.Message;
} else {
throw;
}
}
return obj;
}
public int ExecuteNonQuery(SqlConnection DBConnection, SqlTransaction DBTransaction, bool IsTransRequired)
{
int i = -1;
try {
if ((DBTransaction != null)) {
cmd.Transaction = DBTransaction;
}
i = cmd.ExecuteNonQuery();
} catch (Exception ex) {
if (handleErrors) {
strLastError = ex.Message;
} else {
throw;
}
}
return i;
}
public int ExecuteNonQuery(string commandtext, bool IsTransRequired)
{
SqlConnection DBConnection = null;
SqlTransaction DBTransaction = null;
int i = -1;
try {
cmd.CommandText = commandtext;
if (((DBConnection == null))) {
this.Open();
DBConnection = (SqlConnection)this.cmd.Connection;
if (IsTransRequired == true) {
if (((DBTransaction == null))) {
DBTransaction = DBConnection.BeginTransaction();
}
}
i = this.ExecuteNonQuery(DBConnection, DBTransaction, IsTransRequired);
if ((DBTransaction != null)) {
DBTransaction.Commit();
}
}
} catch (Exception ex) {
if ((DBTransaction != null)) {
DBTransaction.Rollback();
}
if (handleErrors) {
strLastError = ex.Message;
} else {
throw;
}
} finally {
this.Close();
}
return i;
}
public DataSet ExecuteDataSet()
{
SqlDataAdapter da = null;
DataSet ds = null;
try {
da = new SqlDataAdapter();
da.SelectCommand = (SqlCommand)cmd;
ds = new DataSet();
da.Fill(ds);
} catch (Exception ex) {
if ((handleErrors)) {
strLastError = ex.Message;
} else {
throw;
}
}
return ds;
}
public DataSet ExecuteDataSet(string commandtext)
{
DataSet ds = null;
try {
cmd.CommandText = commandtext;
ds = this.ExecuteDataSet();
} catch (Exception ex) {
if (handleErrors) {
strLastError = ex.Message;
} else {
throw;
}
}
return ds;
}
public string CommandText{
get {
return cmd.CommandText;
}
set {
cmd.CommandText = value;
cmd.Parameters.Clear();
}
}
public IDataParameterCollection Parameters{
get {return cmd.Parameters;}
}
public void AddParameter(string paramname, object paramvalue)
{
SqlParameter param = new SqlParameter(paramname, paramvalue);
cmd.Parameters.Add(param);
}
public void AddParameter(IDataParameter param)
{
cmd.Parameters.Add(param);
}
public string ConnectionString {
get { return strConnectionString; }
set { strConnectionString = value; }
}
private void Open()
{
cmd.Connection.Open();
}
private void Close()
{
cmd.Connection.Close();
}
public bool HandleExceptions{
get {return handleErrors;}
set {handleErrors = value;}
}
public string LastError{
get {return strLastError;}
}
public void Dispose()
{
cmd.Dispose();
}
}
}

The distinguished name contains invalid syntax error

I'm trying using LDAP to authenticate user, but I have a problem with LDAP.
This is my code:
string hostOrDomainName = "MrHand-PC";
string targetOu = "cn=Huy Pham,ou=people,dc=example,dc=com";
// create a search filter to find all objects
string ldapSearchFilter = "uid=pdhuy";
// establish a connection to the directory
LdapConnection connection = new LdapConnection(hostOrDomainName);
Console.WriteLine("\r\nPerforming a simple search ...");
SearchRequest searchRequest = new SearchRequest(targetOu, ldapSearchFilter,
System.DirectoryServices.Protocols.SearchScope.OneLevel, null);
// cast the returned directory response as a SearchResponse object
SearchResponse searchResponse =
(SearchResponse)connection.SendRequest(searchRequest);
The last line throws an exception: The distinguished name contains invalid syntax.
Can anyone help my solve this problem?
To authenticate against LDAP, you can try the following (domain, username and password are arguments):
bool IsAuthenticated = false;
string domainAndUsername = domain + #"\" + username;
string dirContext = GetAuthenticatingDirectory(domain);
using (DirectoryEntry entry = new DirectoryEntry("LDAP://" + dirContext, domainAndUsername, password))
{
try
{
Object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if (result != null)
{
IsAuthenticated = true;
}
}
catch (Exception e)
{
//handle appropriately according to your requirements
}
}
return IsAuthenticated;
where GetAuthenticatingDirectory() is defined as
private string GetAuthenticatingDirectory(string domain)
{
string authenticatingDirectory = string.Empty;
string dotComDomain = domain + #".com";
// Connect to RootDSE
using (DirectoryEntry RootDSE = new DirectoryEntry("LDAP://rootDSE"))
{
// Retrieve the Configuration Naming Context from RootDSE
string configNC = RootDSE.Properties["configurationNamingContext"].Value.ToString();
// Connect to the Configuration Naming Context
using (DirectoryEntry configSearchRoot = new DirectoryEntry("LDAP://" + configNC))
{
// Search for all partitions where the NetBIOSName is set.
using (DirectorySearcher configSearch = new DirectorySearcher(configSearchRoot))
{
configSearch.Filter = ("(NETBIOSName=*)");
// Configure search to return dnsroot and ncname attributes
configSearch.PropertiesToLoad.Add("dnsroot");
configSearch.PropertiesToLoad.Add("ncname");
using (SearchResultCollection forestPartitionList = configSearch.FindAll())
{
// Loop through each returned domain in the result collection
foreach (SearchResult domainPartition in forestPartitionList)
{
// domainName like "domain.com". ncName like "DC=domain,DC=com"
string domainName = domainPartition.Properties["dnsroot"][0].ToString();
string ncName = domainPartition.Properties["ncname"][0].ToString();
if (dotComDomain.Equals(domainName, StringComparison.OrdinalIgnoreCase))
{
authenticatingDirectory = ncName;
break;
}
}
}
}
}
}
return authenticatingDirectory;
}

Resources