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() + ">");
Related
I'm trying to get user data from the active directory. Authentication process is true.
var context = new PrincipalContext(ContextType.Domain, "localhost-ad.local", "OU=LocalOu,DC=localhost-ad,DC=local", ContextOptions.Negotiate);
var login = context.ValidateCredentials("user.name", "password", ContextOptions.Negotiate);
But PrincipalSearcher returns a wrong username or password.
var user = new UserPrincipal(context);
var searcher = new PrincipalSearcher(user);
var searchResults = searcher.FindAll();
List<UserPrincipal> results = new List<UserPrincipal>();
foreach (Principal p in searchResults)
{
results.Add(p as UserPrincipal);
}
return results;
How can I solve this problem?
I think your problem may stem from a misunderstanding of what PrincipalContext.ValidateCredentials does.
It does not authenticate the context on the domain or allow access to the domain in any way, all it does is check if the username and password are correct and return True or False.
Instead you can authenticate with the domain as so:
var context = new PrincipalContext(ContextType.Domain, "localhost-ad.local",
"OU=LocalOu,DC=localhost-ad,DC=local", "user.name", "password");
Working with Active directory in an ASP.net CORE MVC website,
I can get many user property like diplayName, emailAdress...
But I cannot find the departement of the user.
Get user informations :
UserPrincipal user = UserPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain), Environment.UserName);
But user haven't a property "Department".
I've try :
DirectoryEntry directoryEntry = user.GetUnderlyingObject() as DirectoryEntry;
var property = "department";
if (directoryEntry.Properties.Contains(property))
{
var dep = directoryEntry.Properties[property].Value.ToString();
}
No departement property neither.
EDIT
Here's a list of properties available : "objectClass, cn, sn, title, description, userCertificate, givenName, distinguishedName, instanceType, whenCreated, whenChanged, displayName, uSNCreated, memberOf, uSNChanged, proxyAddresses, homeMDB, mDBUseDefaults, mailNickname, name, objectGUID, userAccountControl, badPwdCount, codePage, countryCode, badPasswordTime, lastLogon, pwdLastSet, primaryGroupID, objectSid, accountExpires, logonCount, sAMAccountName, sAMAccountType, showInAddressBook, legacyExchangeDN, userPrincipalName, objectCategory, dSCorePropagationData, lastLogonTimestamp, textEncodedORAddress, mail and Lot of msExchange"
This works for me (using a mixture of AccountManagement and DirectoryServices):
var ad = new PrincipalContext(ContextType.Domain, DOMAIN);
var u = new UserPrincipal(ad) {SamAccountName = Environment.UserName};
using (var search = new PrincipalSearcher(u))
{
var user = (UserPrincipal) search.FindOne();
DirectoryEntry dirEntry = (DirectoryEntry)user.GetUnderlyingObject();
string dept = dirEntry.Properties["Department"].Value.ToString();
Console.WriteLine(dept);
}
This requires the following using:
using System;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
To search for an employee's unit
Use value
Department = directoryEntry.Properties["subdivision"].Value as string,
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.
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
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);
}
}