Trouble Authenticating ASP.NET Users Against Active Directory - c#

I replaced our domain name with "demo"... please ignore missing commas and such in the image below.
My question is as follows:
I want to authenticate the SBSUsers in my ASP.NET web application. I cannot figure out what my active directory path needs to be in order to get it to work...
When I set it as follows, it fails to authenticate (I assume because my users are not under that path)... but it doesn't give me an error:
string adPath = "LDAP://ac-dc01.demo.local:389/CN=Configuration,DC=demo,DC=local";
string domainAndUsername = domain + #"\" + username;
DirectoryEntry entry = new DirectoryEntry(adPath, domainAndUsername, pwd);
// 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
adPath = result.Path;
_filterAttribute = (String)result.Properties["cn"][0];
When I set it to what I think it should be, it errors on the entry.NativeObject line.
string adPath = "ldap://ac-dc01.demo.local:389/OU=SBSUsers,OU=Users,OU=MyBusiness,DC=demo,DC=local";
Any ideas? Do I need to open it up for "global" access somehow? If so, how would I go about doing that?
I was able to successfully connect using another piece of software...

this is what you can try.. also are you sure that your DC=Demo and DC=Local those look like OU's to me
const string Domain = "ServerAddress:389";
const string constrParts = #"OU=Users,DC=domain,DC=com";
const string Username = #"someusername";
PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, Domain, constrParts);
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, username);

This is how we connect to our AD and it works great:
<yourConfig>LDAP://ADServerName/OU=GROUPNAME,DC=domainName,DC=com</YourConfig>
And here is a sample code on how you can validate a user:
using (PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain,
ENTER YOUR DOMAIN NAME,
This is where the config that I mentioned above comes in,
ContextOptions.Negotiate,
ENTER YOUR AD SERVICE NAME,
ENTER YOUR AD PASSWORD))
{
UserPrincipal oUser = UserPrincipal.FindByIdentity(oPrincipalContext, THE USERNAME THAT YOU WANT TO VALIDATE);
if (oUser != null)
{
oADAcct = new CUserADAcct();
oADAcct.dumpAcctAttrs(oUser);
}
}

Related

Trying to read login name from Active Directory returning null

DirectoryEntry DirEntry = new DirectoryEntry("LDAP://" + domain, null, null, AuthenticationTypes.None);
DirectorySearcher search = new DirectorySearcher(DirEntry);
search.Filter = String.Format("(SAMAccountName={0})", "my_login_name");
search.PropertiesToLoad.Add("cn");
SearchResult result1 = search.FindOne();
myDataTable Users = new myDataTable();
DataRow User;
foreach (SearchResult i in search.FindAll())
{
DirectoryEntry CurrentDirEntry;
User = Users.NewUserRow();
CurrentDirEntry = i.GetDirectoryEntry();
User.FirstName = (string)CurrentDirEntry.Properties["givenname"].Value;
User.LastName = (string)CurrentDirEntry.Properties["sn"].Value;
User.UserName = (string)CurrentDirEntry.Properties["sAMAccountName"].Value;
User.Email = (string)CurrentDirEntry.Properties["mail"].Value;
Users.AddUserRow(User);
}
I'm trying to read some properties from active directory but the value for
sAMAccountName
is always returned as null, i'm wondering why this is so since its being matched in the search filter. Could it be related to access privileges?
I want to return the FirstName, LastName, Email and login Name. I'm getting other properties except login name.
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, my_login_name);
if(user != null)
{
// do something here....
string samAccountName = user.SamAccountName;
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
Update: if you need to search by fields that aren't handled by the .FindByIdentity() call, then you need to use the PrincipalSearcher and a "query-by-example" principal to do your searching:
// 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.....
}
}
Could it be the spacing in ["sAMAccountName "] of :
User.UserName = (string)CurrentDirEntry.Properties["sAMAccountName "].Value;
Try this one , I used it before
VB
Dim myDe As New DirectoryEntry("LDAP://DOMAIN.LOCAL")
Dim deSearcher As New DirectorySearcher(myDe)
Dim userDE As DirectoryEntry
Dim email As String = ""
Try
deSearcher.Filter = "(&(sAMAccountName=" & UserName & "))"
userDE = deSearcher.FindOne().GetDirectoryEntry()
email = userDE.Properties("mail").Value
Catch ex As Exception
End Try
C#
DirectoryEntry myDe = new DirectoryEntry("LDAP://DOMAIN.LOCAL");
DirectorySearcher deSearcher = new DirectorySearcher(myDe);
DirectoryEntry userDE = default(DirectoryEntry);
string email = "";
try {
deSearcher.Filter = "(&(sAMAccountName=" + UserName + "))";
userDE = deSearcher.FindOne().GetDirectoryEntry();
email = userDE.Properties("mail").Value;
} catch (Exception ex) {}
I'm not sure how C# handles it but I've seen LDAP-libs returning attribute names all in lower case. So it might help to simply call for samaccountname instead of sAMAccountName.

Connect to correct ad domain using User.Identity.Name?

I am using User.Identity.Name to get the user logged in with my web app.
Then I am querying AD to get properties for that user:
string[] sx = User.Identity.Name.Split('\\');
var username = sx[sx.Count() - 1];
DirectorySearcher searcher = new DirectorySearcher();
searcher.Filter = string.Format(Filter, username);
SearchResult user = searcher.FindOne();
Now I want to add domain support:
string[] sx = UserIdentityName.Split('\\');
var username = sx[sx.Count() - 1];
var domain = sx[0];
DirectoryEntry entry = new DirectoryEntry("LDAP://DC=" + domain));
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = string.Format(Filter, username);
SearchResult user = searcher.FindOne();
This does not work, perhaps because the domain is not fully qualified. So I have DC=intra where I would need DC=intra,DC=contoso,DC=com, and DC=sub where I would need DC=sub,DC=intra,DC=contoso,DC=com.
How can I still connect to the correct AD domain? Can I get full qualified username (UPN name) for user that is logged in, or can I get correct AD domain of user logged in, or how can I achieve this?
This won't work as you've discovered. Instead, bind based on the SID using something like this:
WindowsIdentity current = (WindowsIdentity)User.Identity;
DirectoryEntry userObject = new DirectoryEntry("LDAP://<SID=" + current.User.ToString() + ">");

Authenticating another user when using Windows Authentication

I have a .NET MVC 4 application that uses Windows authentication. Some users are administrators, and need to be able to enter data on behalf of other users.
I have a text box where the admin enters the name of another user. How can I check to verify that the text entered is an existing Windows username?
You could use the FindByIdentity method:
string username = "Some username you retrieved from the TextBox";
using (var ctx = new PrincipalContext(ContextType.Domain, "YOUR_DOMAIN"))
using (var user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, username))
{
bool userExists = user != null;
// here you know whether the user exists or not
}
You can query the Active Directory of your organization for this.
DirectoryEntry entry = new DirectoryEntry("LDAP://DomainName");
DirectorySearcher Dsearch = new DirectorySearcher(entry);
String Name="Richmond";
dSearch.Filter = "(&(objectClass=user)(l=" + Name + "))";
See this article:
http://www.codeproject.com/Articles/6778/How-to-get-User-Data-from-the-Active-Directory

Login Authentication using Active Directory in the Intranet...Possible?

I am creating this project to be deployed in our company's intranet. I am using this code to authenticate the users login:
entry.Username = strUserName;
entry.Password = strPassword;
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = "(objectclass=user)";
try
{
searcher.FindOne();
return true;
}
It working well on my localhost, but when I deployed it the intranet, I can't log in.
Now my question is, can I access the Directory over the intranet? or is there a better way to achieve this?
A simpler method would be to use System.DirectoryServices and System.DirectoryServices.AccountManagement
Use this in a function returning Boolean:
Dim context As PrincipalContext = New PrincipalContext(ContextType.Domain, domainName)
If context.ValidateCredentials(userAlias, userPassword, ContextOptions.Negotiate) Then
Return True
Else
Return False
End If
The snippet is in VB, but you get the idea. Replace domainName with your domain name, userAlias with your username, and userPassword with your password.
This worked great for me in the past:
var ldapConnectionString = "LDAP://servername/CN=Users,DC=domainname,DC=com";
using (var de = new DirectoryEntry(ldapConnectionString, username, password, AuthenticationTypes.Secure))
{
if(de.NativeObject != null)
{
// user is valid ...
}
}
You need a reference to: System.DirectoryServices

c# Log In click event using authentication against Active Directory through LDAP

I am quite new to c# and LDAP, I'm doing this project so that I could learn about them in a more hands on approach.
What I'm trying to create is a Log in form that has a log in click event that would authenticate the username and password after the user enters them through the active directory using LDAP.
I have read Managing Directory Security Principals in the .NET Framework 3.5 to be able to understand this subject better and I have also gone through similar topics here this one dealing with the validation in itself (c# - Validate a username and password against Active Directory?) and this one authenticating a username (c# against Active Directory over LDAP)
From the first linked topic I had learned that the following code should do the trick in authenticating a username and password:
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "LDAP://example.string.com/OU=Users, Dc=example, Dc= string, DC=com"))
{
bool isValid = pc.ValidateCredentials(User, Password);
}
So my approach to incorporate this to a click event was as follows:
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "LDAP://example.string.com/OU=Users, Dc=example, Dc= string, DC=com"))
bool isValid = pc.ValidateCredentials(User, Password);
if(isValid)
{
Main m = new Main();
this.Close();
m.Show();
}
else
{
MessageBox.Show("Invalid Username and/or Password","Error!");
textBox1.Clear();
textBox2.Clear();
textBox1.Focus();
}
Which is giving me a bool error of Embedded Statement.
I tried the other approach I had read from the second post which was to use this code which authenticates only Username:
PrincipalContext pc = new PrincipalContext(ContextType.Domain, "LDAP://example.com/OU=Computers,OU=Users,dc=example,dc=com");
UserPrincipal user = UserPrincipal.FindByIdentity(pc, "username");
bool userExists = (user != null);
But I found that I wont be able to authenticate a password using this method as UserPrincipal.FindByPassword does not exist.
I have also tried it this way but again .Password does not exist:
PrincipalContext pc = new PrincipalContext(ContextType.Domain,"LDAP://....");
UserPrincipal qbeUser = new UserPrincipal(pc);
qbeUser.EmployeeId = User;
//.Password does not exist
UserPrincipal qbePassword = new UserPrincipal(pc);
qbePassword.Password = Password;
// create your principal searcher passing in the QBE principal
PrincipalSearcher srchUser = new PrincipalSearcher(qbeUser);
PrincipalSearcher srchPass = new PrincipalSearcher(qbePassword);
// try to find that user and password
UserPrincipal founduser = srchUser.FindOne() as UserPrincipal;
UserPrincipal foundpass = srchPass.FindOne() as UserPrincipal;
if (founduser != null)
{
if (foundpass != null)
{
Main m = new Main();
this.Close();
m.Show();
}
else
{
MessageBox.Show("Password Not Valid.");
textBox2.Clear();
textBox2.Focus();
}
}
else
{
MessageBox.Show("Username Not Valid.");
textBox1.Clear();
textBox1.Focus();
}
Can someone kindly please instruct me as how one should correctly approach this.
Thank you in advance.
I have done this but not with PrincipalContext. Instead I have found many people struggling using that object.
My implemenatation was a winforms form and the submit button calls a method executing the 4 las lines of the code below.
I tested against this magnificent free to test LDAP server
var path = "LDAP://ldap.forumsys.com:389/dc=example,dc=com";
var user = $#"uid={username},dc=example,dc=com";
var pass = "password";
var directoryEntry = new DirectoryEntry(path, user, pass, AuthenticationTypes.None);
var searcher = new DirectorySearcher(directoryEntry);
searcher.PropertiesToLoad.Add("*");
var searchResult = searcher.FindOne();
I donĀ“t understand exactly what all of this lines does.
Important tips
On the path the "LDAP://" string should be on block mayus.
In the user, according to the test server you use "cn=username-admin" for validating admins, be sure to also set Authentication type to ServerBind.

Categories

Resources