I am trying to implement active directory authentication but I am getting exception which is like
System.Runtime.InteropServices.COMException was caught
Message=Unknown error (0x80005000)
Source=System.DirectoryServices
ErrorCode=-2147463168
StackTrace:
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
at System.DirectoryServices.DirectorySearcher.FindOne()
at ConsoleApplication1.ADAuthentication.AuthenticateADUsers(String userNameWithDomain, String password) in C:\Users\awadhendrat\documents\visual studio 2010\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 83
at ConsoleApplication1.Program.Main(String[] args) in C:\Users\awadhendrat\documents\visual studio 2010\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 23
InnerException:
I don't know what I am missing. Following code I have written for implementing AD Authentication.
public bool AuthenticateADUsers(string userNameWithDomain, string password)
{
DirectoryEntry objDirectoryEntry = null;
DirectorySearcher objDirectorySearcher = null;
try
{
objDirectoryEntry = new DirectoryEntry("https://ab.hotels.com/", userNameWithDomain, password, AuthenticationTypes.Delegation);
objDirectorySearcher = new DirectorySearcher(objDirectoryEntry);
objDirectorySearcher.Filter = string.Format("(&(objectClass=user)(objectCategory=user) (sAMAccountName={0}))", userNameWithDomain.Substring(0, userNameWithDomain.IndexOf('#')));
objDirectorySearcher.PropertiesToLoad.Add("msRTCSIP-PrimaryUserAddress");
var result = objDirectorySearcher.FindOne();
if (result != null)
return true;
else
return false;
}
catch
{
throw;
}
}
I have done some google but not getting helpful. Here I have few confusion like every where they written LDAP://somedomain/ but here I have https://somedomain.com another confusion is my test application is on one domain and provided domain is on another server.
When I open links provided by client which is used for AD Authentication then it opens Open Office Web Access.
I don't how to solve this problem.
Thanks.
According to this answer (and some quick code I wrote to test this), it's a permission problem (possibly related to your use of an https URL for the AD path, checkout this code for building a DirectoryEntry or the fact that you are doing a full AD search with the same user you are trying to authenticate).
Related
I have an asp.net application that uses delegation to perform actions on the Active Directory as the authenticating user. The application works perfectly on some computers and doesn't work at all on other computers, on these other computers they receive a COMexception error code 0x80072020 the stack trace is:
System.Runtime.InteropServices.COMException (0x80072020): An operations error occurred.
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
at System.DirectoryServices.DirectorySearcher.FineOne()
at ResetUnlockAccount.ResetUnlockAccount.ExecuteImpersonation(String username)
The code that is throwing the error is:
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
ctx=winId.Impersonate();
using (DirectoryEntry directoryObject = new DirectoryEntry(ROOT))
{
using (DirectorySearcher search = new DirectorySearcher(directoryObject))
{
search.Filter = "(&(objectClass=user)(SAMAccountName=username))";
search.SearchScope = SearchScope.Subtree;
///////////////////////////////////////////////////////////////////
This line is causing the issue.
---------->SearchResult result = search.FindOne();
using (DirectoryEntry user = result.GetDirectoryEntry())
{
user.Invoke("SetPassword", new object[] { password });
user.Properties["pwdLastSet"][0] = 0;
user.CommitChanges();
lblOutput.Text = "It worked";
}
}
}
}
catch (Exception ex)
{
lblOutput.Text += ex.ToString();
}
finally
{
if (ctx != null)
ctx.Undo();
}
At first I thought it was a User permission issue, so I tested it by trying my credentials on one of the computers that was having issues, I encountered the same issues. To confirm it wasn't User permission issues I tried it on my workstation with the other persons credentials and it worked perfectly.
I wrote a quick test program that would show me the impersonation level of the users, when working correctly it should be Delegation. When I ran it on my machine the output was:
Authentication Type: Negotiate
Token: 9999
Name: domain\username
Is Authenticated: True
Impersonation level: Delegation
When I ran it on the other Workstation:
Authentication Type: Negotiate
Token: 9999
Name: domain\username
Is Authenticated: True
Impersonation level: Impersonation
Server: IIS 7.0
Browser: IE 8
I don't know what is causing the issue with only certain computers, if anyone knows of a specific setting that should be changed for delegation to work properly I would be grateful. Below I have posted two other links that will help give more insight into my problem.
.GetDirectoryEntry throws COM exception, code:0x800720720 when attempting to bind to object
asp.net application userprincipal.findbyidentity works with browser on server, throws exception from my machine
I have the following code to retrieve AD groups of a given user name in my MVC3 web application:
PrincipalContext userDomain = new PrincipalContext(ContextType.Domain, username.Split('\\')[0]);
UserPrincipal user = UserPrincipal.FindByIdentity(userDomain, username);
PrincipalSearchResult<Principal> memberOfGroups = user.GetGroups();
IEnumerator<Principal> memberOfGroupsEnumerator = memberOfGroups.GetEnumerator();
List<string> userADGroups = new List<string>();
try
{
while (memberOfGroupsEnumerator.MoveNext())
{
userADGroups.Add(memberOfGroupsEnumerator.Current.ToString());
}
}
catch
{
// When trying to access AD groups of a different domain, issues can arise at the end of the enumerator. These may be ignored.
}
This works fine locally but when deployed onto another machine on the network errors out with the following error:
An operations error occurred.
The stack trace for the error:
System.DirectoryServices.DirectoryServicesCOMException (0x80072020): An operations error occurred.
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.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext
context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, String identityValue)
at MvcSFIWebSite.Models.User..ctor(String username)
The error message is rather ambiguous and I am unable to figure out what is happening as it works fine locally.
The IIS on the machine used for deployment uses a custom account instead of the AppPool identity. Should this account be granted any permissions to access the AD group directory? Are any other settings explicitly required in IIS for this to work?
Any suggestions would be very helpful. Thanks in advance.
The issue was because identity_impersonate was set to true in web.config so the user token which was being passed was a secondary token and hence could not access the Active Directory.
This answer solved my issue.
We had this issue also, but the configuration-file did not had this setting. But after some checking all kinds of options in IIS i found a similar option in the UI.
When Impersonation is enabled and Windows authentication is enabled Active directory won't accept the credentials of the impersonated user.
You can solve that by using Basic Authentication instead of windows authentication.
PS. always use SSL with basic authentication
Since I saw lot of posts about the exception which is shown below, And most of guys were stuck with it painfully.
Exception Message: "The server is not operational"
Source: "System.DirectoryServices"
Recently It happened on me. But finally I figure it out .I thought I should share my experience here so that in future it could be helpful for someone else who has the same problem as me.
The program I was working with is using AD authentication. And it works fine in my computer which belongs to the AD Domain. The code is below.
public static bool IsAuthenticated(string srvr, string usr, string pwd)
{
bool authenticated = false;
try
{
DirectoryEntry deRoot = new DirectoryEntry(srvr);
DirectoryEntry entry = new DirectoryEntry(srvr, usr, pwd);
object nativeObject = entry.NativeObject;//this will cause exception Until setting the right DNS address.
authenticated = true;
}
catch (DirectoryServicesCOMException cex)
{
//not authenticated; reason why is in cex
HttpContext.Current.Response.Write(cex.Message);
}
catch (Exception ex)
{
//not authenticated due to some other exception [this is optional]
HttpContext.Current.Response.Write(ex.Message);
}
return authenticated;
}
One day as our IT environment requirement changed, My computer IP is switched from 10.50.70.64 to 169.254.135.249. Because my net adapter IP and DNS always set to Obtain address automatically.In this case , I can log in my computer using the AD account successfully. But the program run with a big fat exception. So I doubted if there is something wrong with my Net Adapter settings. Finally I found If I set the right DNS address of our IT environment. The Exception was gone. I don't know why. So I also hope someone can explain more about it. Thanks.
Before authenticating user and password in AD domain, it need to parse the domain path against DSN server.
I can check if user is Domain Administrator by the following lines of code:
using (DirectoryEntry domainEntry = new DirectoryEntry(string.Format("LDAP://{0}", domain)))
{
byte[] domainSIdArray = (byte[])domainEntry.Properties["objectSid"].Value;
SecurityIdentifier domainSId = new SecurityIdentifier(domainSIdArray, 0);
SecurityIdentifier domainAdminsSId = new SecurityIdentifier(WellKnownSidType.AccountDomainAdminsSid, domainSId);
using (DirectoryEntry groupEntry = new DirectoryEntry(string.Format("LDAP://<SID={0}>", BuildOctetString(domainAdminsSId))))
{
string adminDn = groupEntry.Properties["distinguishedname"].Value as string;
SearchResult result = (new DirectorySearcher(domainEntry, string.Format("(&(objectCategory=user)(samAccountName={0}))", userName), new[] { "memberOf" })).FindOne();
return result.Properties["memberOf"].Contains(adminDn);
}
}
More details here
But when the Domain Controller is turned off, or its off-line (without any connections), I get the following error:
The server is not operational.
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)
Is there an ability to check if user is Domain Administrator with turned off Domain Controller?
You can check whether the current user is a Domain administrator without contacting the domain controller.
If your requirement is to check whether arbirary user is a Domain administrator, I don't think you can do it without domain controller.
It's true that Windows cache the login credentials for the disconnected login purpose. The cache is stored and encrypted in HKEY_LOCAL_MACHINE\SECURITY\Cache. By design, the cache can only be descrypted by LSA. If you find some other ways to decrypt or query the information without going through LSA, that's a security hole that Microsoft will probably fix it right away. So, the only hope that you have is somehow LSA exposes an API to query the group informations stored in credentials cache. As far as I know, I don't see such an API exists. See here for the documented LSA API.
I'm trying to diagnose a problem with a server application running on a Client site. Said application authenticates user credentials against a Domain Controller in an AD environment. The behavior we're seeing is periodically no users can authenticate through the server.
We've essentially traced the failure to the "bind" failing. To further diagnose the issue, I built a super simple tool that does two types of binds: one using an LDAP server bind, and one use WinNT bind. Our server application only does LDAP bind, but to add a control, I threw in the WinNT bind.
public static void DoWinNTBind(string domain, string login, string password)
{
Logger.Log("Starting WinNT Bind to {0}",domain);
try
{
var serverPath = String.Format("WinNT://{0}",domain);
Logger.Log("Creating DirectoryEntry object for {0} on domain {1}", login, serverPath);
using (DirectoryEntry de = new DirectoryEntry(serverPath, login, password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing))
{
if (!de.NativeObject.Equals(null))
{
Logger.Log("WinNT Bind Success");
}
else
{
Logger.Log("WinNT Bind Failed");
}
}
}
catch(Exception ex)
{
Logger.Log("{0} occured during WinNT Bind: {1}",ex.GetType().Name,ex.Message);
Logger.Log("Stack: {0}",ex.StackTrace);
}
}
public static void DoLDAPBind(string domain,string login, string password)
{
Logger.Log("Starting LDAP Bind to {0}",domain);
try
{
var serverPath = String.Format("LDAP://{0}",domain);
Logger.Log("Creating DirectoryEntry object for {0} on domain {1}", login, serverPath);
using (DirectoryEntry de = new DirectoryEntry(serverPath, login, password, AuthenticationTypes.Secure | AuthenticationTypes.Sealing))
{
if (!de.NativeObject.Equals(null))
{
Logger.Log("LDAP Bind Success");
}
else
{
Logger.Log("LDAP Bind Failed");
}
}
}
catch(Exception ex)
{
Logger.Log("{0} occured during LDAP Bind: {1}",ex.GetType().Name,ex.Message);
Logger.Log("Stack: {0}",ex.StackTrace);
}
}
As you can see, there is not much code other than using System.DirectoryServices.DirectoryEntry to connect to a DC.
The resulting logfile is (name and domain masked).
6/29/2010 2:52:17 PM: Performing AD
binds for user1 6/29/2010 2:52:17 PM:
Starting LDAP Bind to xxx.xxx
6/29/2010 2:52:17 PM: Creating
DirectoryEntry object for on domain
LDAP://xxx.xxx 6/29/2010 2:52:17 PM:
DirectoryServicesCOMException occured
during LDAP Bind: Logon failure:
unknown user name or bad password.
6/29/2010 2:52:17 PM: Stack: at
System.DirectoryServices.DirectoryEntry.Bind(Boolean
throwIfFail) at
System.DirectoryServices.DirectoryEntry.Bind()
at
System.DirectoryServices.DirectoryEntry.get_NativeObject()
at
AdmitOne.Superglue.ActiveDirectoryHelper.DoLDAPBind(String
domain, String login, String password)
in
C:\Projects\Galapagos\branches\Contract\2.0_SN_Peer\Src\Tools\Superglue\ActiveDirectoryHelper.cs:line
47 6/29/2010 2:52:17 PM: Starting
WinNT Bind to xxx.xxx 6/29/2010
2:52:17 PM: Creating DirectoryEntry
object for user1 on domain
WinNT://xxx.xxx 6/29/2010 2:52:18 PM:
WinNT Bind Success
So the same user name fails to bind using LDAP, but succeeds using WinNT!
Locally in our test environment, we don't see this behavior, both LDAP and WinNT succeed with no issues.
So I'm stuck. I'd like to say it's a problem with their AD environment, but without a smoking gun, I can't.
I'm first asking on Stack, to ensure that my bind code is correct. Afterwhich, I'll probably need to reask on Serverfault, which is the more appropriate place to ask for AD specific issues.
It turns out this is not a code issue, but instead the customer's AD environment is having issues with Kerberos.
Specifically the Secure/Sealing flags instruct the LDAP provider to use only Kerberos to securely negotiate auth.
Since Kerberos is not supported by the WinNT provider, there is no issue binding with the WinNT provider.