I had my code to check the current logged user , it is worked well on local host but when I deployed on server it doesn't work .
private void checkUser()
{
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = string.Format(CultureInfo.InvariantCulture, "(sAMAccountName={0})", Page.User.Identity.Name);
SearchResult findUser = searcher.FindOne();
if (findUser != null)
{
DirectoryEntry user = findUser.GetDirectoryEntry();
string Mobile = user.Properties["Mobile"].Value.ToString();
string Login = user.Properties["sAMAccountName"].Value.ToString();
if (user.Properties["Department"].Value != null)
LoggedDepartement = user.Properties["Department"].Value.ToString();
string title = user.Properties["title"].Value.ToString();
data = user.Properties["thumbnailPhoto"].Value as byte[];
}
}
Related
I have been using this code because there is an error:
Execution of authentication request returned unexpected result: 404
DataSet ds = new DataSet();
ds.Tables.Add("GmailContact");
ds.Tables[0].Columns.Add("EmailId");
RequestSettings rs = new RequestSettings("GetGmailContact", txtUsername.Text, txtPassword.Text);
rs.AutoPaging = true;
ContactsRequest cr = new ContactsRequest(rs);
Feed<Contact> f = cr.GetContacts();
foreach (Contact t in f.Entries)
{
foreach (EMail email in t.Emails)
{
DataRow row = ds.Tables[0].NewRow();
row["EmailId"] = email.Address.ToString();
ds.Tables[0].Rows.Add(row);
}
}
GridView1.DataSource = ds.Tables[0];
GridView1.DataBind();
lblStatus.Text = "Total Contact For" + txtUsername.Text + ":" + ds.Tables[0].Rows.Count.ToString();
Step
1 Go to https://console.developers.google.com/project and create project.
2 Select project, select APIs & auth from top left corner menu.
3 Select Credentials
4 Create OAuth with button Create new Client ID (Application type - Installed Aplication.
5 Fill field Product Name
6 Save
After that you got Client ID for native application with: Client ID, Client secret, Redirect URIs
Install Google.Apis.Auth from NuGet
Code
string clientId = null; // https://console.developers.google.com/project/xxx
string clientSecret = null; // https://console.developers.google.com/project/xxx
string accessCode = null; // You will get this code after GetAccessToken method
string redirectUri = null; // https://console.developers.google.com/project/xxx
string applicationName = null; // https://console.developers.google.com/project/xxx
// Scopes https://support.google.com/a/answer/162106?hl=en
string scopes = null; // put your scope like https://www.google.com/m8/feeds/
string accessType = "offline";
string tokenType = "refresh";
OAuth2Parameters parameters = new OAuth2Parameters
{
ClientId = clientId,
ClientSecret = clientSecret,
RedirectUri = redirectUri,
Scope = scopes,
AccessType = accessType,
TokenType = tokenType
};
if (accessCode == null)
{
string url = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
// Start webbrowser
Process.Start(url);
// Load code from web via popup, etc.
parameters.AccessCode = accessCodeFromWeb;
}
// Check accessToken and refreshToken
// After first acceess with GetAccessToken you will get that information
if (accessToken == null || refreshToken == null)
{
OAuthUtil.GetAccessToken(parameters);
// Save yours accessToken and refreshToken for next connection
accessToken = parameters.AccessToken;
refreshToken = parameters.RefreshToken;
}
else
{
// Restore your token from config file, etc.
parameters.AccessToken = accessToken;
parameters.RefreshToken = refreshToken;
}
RequestSettings rs = new RequestSettings(applicationName, parameters);
return new ContactsRequest(rs);
I had my code to retrieve logged user details , every thing is OK but
i cannot retrieve the user image .
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = string.Format(CultureInfo.InvariantCulture, "(sAMAccountName={0})", Environment.UserName);
//SearchResult findUser = searcher.FindOne();
foreach (SearchResult findUser in searcher.FindAll())
{
if (findUser != null)
{
DirectoryEntry user = findUser.GetDirectoryEntry();
string userName = user.Properties["displayName"].Value.ToString();
string departement = user.Properties["Department"].Value.ToString();
string title = user.Properties["title"].Value.ToString();
string[] rt = new string[] { Login, userName, Email, Mobile };
Lbl_User.Text = userName;
Lbl_Administrative.Text = departement;
Lbl_Position.Text = title;
}
}
I've just taken your code and made a method out of it just to retrieve the image. You would need to refactor it, to either get only the byte[] or thw whole image.
//add this
using System.Drawing;
static Image GetPhotoFromAD(string userName)
{
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = string.Format(CultureInfo.InvariantCulture, "(sAMAccountName={0})", userName);
//SearchResult findUser = searcher.FindOne();
foreach (SearchResult findUser in searcher.FindAll())
{
if (findUser != null)
{
byte[] photodata = findUser.Properties["jpegPhoto"].Value as byte[];
using (MemoryStream str = new MemoryStream(photodata))
{
return Bitmap.FromStream(str);
}
}
}
}
If you only want the raw data, the important bit is byte[] photodata = user.Properties["jpegPhoto"].Value as byte[];
The binary image should be stored in property called thumbnailPhoto.
var photo = user.Properties["thumbnailPhoto"];
if (photo != null) {
byte[] buffer = (byte[])photo.Value;
//var bitmap = new Bitmap(new MemoryStream(buffer, false));
//bitmap.Save(#"c:\test.bmp");
}
Now, given the fact that you tagged question as asp.net you'll have to write generic handler (.ashx) for retrieving the image. This handler should write content of
photo.Value
into response output stream and set content type to image/bmp
In your control/page just reference the handler like
<img src="/GenericHandler.ashx" alt="My image" />
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.
I know there are lots of methods already given in stackoverflow but in my case all of them taking too long time. I post a method which takes less time but still it is too long to implement. Please help me so that it takes less execution time. Also take consideration that i am using .net 2.0 framework.
try
{
List<string> lstEmails = new List<string>();
string filter1 = string.Format("(anr={0})", "groupname");
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = filter1;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("mail");
IEnumerable res = (IEnumerable)searcher.FindOne().GetDirectoryEntry().Invoke("members");
//IEnumerable<string> rest = (IEnumerable<string>)res;
if (res != null)
{
try
{
int index = 0;
foreach (IEnumerable resl in res)
{
DateTime start = DateTime.Now;
DirectoryEntry dr = new DirectoryEntry(resl);
string strEmail = null;
if (dr.Properties["mail"].Value != null)
{
strEmail = dr.Properties["mail"].Value.ToString();
Console.WriteLine(strEmail);
DateTime stop = DateTime.Now;
Console.WriteLine((stop - start).TotalMinutes.ToString());
index++;
Console.WriteLine(index.ToString());
}
if (!string.IsNullOrEmpty(strEmail))
{
// groupMemebers.Add("sam",strEmail);
}
}
}
catch { }
}
}
catch { }
This is your suggested method Daro..
DirectoryContext context = new DirectoryContext(DirectoryContextType.Domain, domain, "domainname" + strLDAPUserName, strLDAPPassword);
DomainController controller = DomainController.FindOne(context);
DirectoryEntry entry = new DirectoryEntry(string.Format("LDAP://{0}",controller.Domain), strLDAPUserName, strLDAPPassword, AuthenticationTypes.Secure);
List<string> userList = new List<string>();
DateTime StartTime = DateTime.Now;
using (DirectorySearcher ds = new DirectorySearcher(entry))
{
ds.PropertiesToLoad.Add("mail");
ds.PageSize = 10000;
string DistingushiedName = "CN=" + groupName + ",OU=Users,dc=CompanyName,dc=com";
ds.Filter = "(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:="+DistingushiedName+"))";
ds.SearchScope = SearchScope.Subtree;
try
{
foreach (SearchResult user in ds.FindAll())
{
try
{
userList.Add(user.Path);//.Properties["mail"][0].ToString());
}
catch (Exception E)
{
throw new Exception(E.Message);
}
}
}
catch(Exception E)
{
throw new Exception(E.Message);
}
DateTime EndTime = DateTime.Now;
TimeSpan Dif = EndTime.Subtract(StartTime);
}
Here is your solution:-
string[] email = new string[0];
DirectoryEntry entry = new DirectoryEntry("LDAP://OU=Users,dc=me,dc=com", username, password);
string groupName = "GroupName";//Group NAme
DirectorySearcher groupSearch = new DirectorySearcher(entry);
groupSearch.Filter = "(SAMAccountName=" + groupName + ")";
groupSearch.PropertiesToLoad.Add("member");
SearchResult groupResult = groupSearch.FindOne(); // getting the members who belongs to the concern groupname
if (groupResult != null)
{
email = new string[groupResult.Properties["member"].Count]; //creatign an array to store all the email address
for (int iSearchLoop = 0; iSearchLoop < groupResult.Properties["member"].Count; iSearchLoop++)
{
string userName = groupResult.Properties["member"][iSearchLoop].ToString();
int index = userName.IndexOf(',');
userName = userName.Substring(0, index).Replace("CN=", "").ToString(); // the name of the user will be fetched.
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(name=" + userName + ")";
search.PropertiesToLoad.Add("mail");
SearchResult result = search.FindOne(); //finding the mail id
if (result != null)
{
email[iSearchLoop] = result.Properties["mail"][0].ToString(); //assigning the mail id to an array....
}
}
}
Hope this helps you
Easy enough (if your AD is 2003 R2 or higher):
List<string> userList = new List<string>();
DateTime StartTime = DateTime.Now;
using (DirectorySearcher ds = new DirectorySearcher(new DirectoryEntry ("GC://DC=YourDomain,DC=com")))
{
ds.PropertiesToLoad.Add("mail");
ds.PageSize = 10000;
ds.Filter = "(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=YOUR_GROUP'S DN))";
ds.SearchScope = SearchScope.Subtree;
try
{
foreach (SearchResult user in ds.FindAll())
{
try
{
userList.Add(user.Path);//.Properties["mail"][0].ToString());
}
catch (Exception E)
{
throw new Exception(E.Message);
}
}
}
catch(Exception E)
{
throw new Exception(E.Message);
}
DateTime EndTime = DateTime.Now;
TimeSpan Dif = EndTime.Subtract(StartTime);
}
Replace YOUR_GROUP'S DN with the distiguished name of your group...
memberof:1.2.840.113556.1.4.1941:= is the "new" LDAP_MATCHING_RULE_IN_CHAIN operator, and retrieves all group members. Look here to see if your AD is ready and get more information.
Edit:
I gave you an answer, but an explanation might help further.
In general you should avoid ANR searches because they expand to large wildcard OR queries. Use them only if you have no idea which property contains the name you are searching for. They are much slower than explicit AND searches.
Secondly if you have more than one domain, you should turn off referral chasing unless you want to search through all domains until you get a hit. In this case it would be better to do a GC:// than a LDAP:// search to find the object you’re looking for, than do an LDAP search on that object. Depending on what you are looking for the GC query could well be enough
Edit 2:
Modified the code to give more error information and get the user path instead of E-Mail.
Hey this is the correct way...
try
{
List<string> ReturnArray = new List<string>();
DirectoryContext context = new DirectoryContext(DirectoryContextType.Domain, domainName, domainName + "\\" + UserName, Password);
DomainController controller = DomainController.FindOne(context);
string LDAPAddress = string.Format("LDAP://{0}", controller.Domain);
DirectoryEntry deDirEntry = new DirectoryEntry(LDAPAddress, UserName, Password);
deDirEntry.AuthenticationType = AuthenticationTypes.Secure;
DirectorySearcher mySearcher = new DirectorySearcher(deDirEntry);
mySearcher.PropertiesToLoad.Add("distinguishedName");
string sFilter = String.Format("(&(objectcategory=group)(cn=" + GroupName + "))");
mySearcher.Filter = sFilter;
mySearcher.Sort.Direction = SortDirection.Ascending;
mySearcher.Sort.PropertyName = "cn";
SearchResult result;
DirectoryEntry ResultEntry;
result = mySearcher.FindOne();
ResultEntry = result.GetDirectoryEntry();
GroupName = ResultEntry.Properties["distinguishedName"].Value.ToString();
mySearcher = new DirectorySearcher(deDirEntry);
mySearcher.PropertiesToLoad.Add("cn");
mySearcher.PropertiesToLoad.Add("mail");
sFilter = String.Format("(&(objectClass=person)(memberOf={0}))", GroupName);
mySearcher.Filter = sFilter;
mySearcher.Sort.Direction = SortDirection.Ascending;
mySearcher.Sort.PropertyName = "cn";
SearchResultCollection results;
results = mySearcher.FindAll();
foreach (SearchResult resEnt in results)
{
ResultPropertyCollection propcoll = resEnt.Properties;
foreach (string key in propcoll.PropertyNames)
{
if (key == "mail")
{
foreach (object values in propcoll[key])
{
if (!String.IsNullOrEmpty(values.ToString()))
{
ReturnArray.Add(values.ToString());
Console.WriteLine(values.ToString());
}
}
}
}
}
return ReturnArray;
}
catch
{
return null;
}
Thanks everyone for your valuable suggesstion
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;
}