Delegation not working on some computers - c#

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

Related

Which roles must have an impersonated user to parse IIS applications?

When executing the following c# code impersonating a user I have an exception (I do not have details on the exception):
public static void CheckIIS()
{
// list al websites on IIS
DirectoryEntry w3svc = new DirectoryEntry("IIS://localhost/W3SVC");
foreach (DirectoryEntry ws in w3svc.Children)
{
if (ws.SchemaClassName != "IIsWebServer")
continue;
//
// Website found!
}
}
Which roles the windows user must have to avoid exceptions?
Thanks.
I guess your exception is "Access denied". This is a common issue when using impersonation authentication.
You can try set this impersonation user being a member of IIS_IUSRS group. It solves the similar problem.

C# LDAP SSL Logon issue on F5 VIP name when LdapEnforceChannelBinding=1 or 2

I have C# Windows Form application to test the LDAP SSL authentication.
Here is the code. First, I made a function.
using System.DirectoryServices;
private bool VerifyDomainUserUsignLDAP(string UserName, string Password, string Domain,string mode, out string message)
{
bool retVal = false;
message = null;
DirectoryEntry de;
try
{ if (mode =="Plain")
//plain mode
de = new DirectoryEntry(Domain, UserName, Password);
else
//SSL mode
de = new DirectoryEntry(Domain, UserName, Password,
AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer);
DirectorySearcher ds = new DirectorySearcher(de);
SearchResult sr= ds.FindOne();
lblResult.Text = "Authentication Passed! " + sr.ToString();
retVal = true;
}
catch (Exception ex)
{
retVal = false;
lblResult.Text = ex.Message;
}
return retVal;
}
My problem is the invoke.
Share with some background first.
We have multiple domain control servers (Windows). dcserver001.mydomain.com is one of them. (of course, we have dcserver002.mydomain.com, dcserver003.mydomain.com, etc). each server provides LDAPS service.
And we created a VIP name ldap.mydomain.com in F5 (Load balance), we put all above dc servers into the Load balance. All DC servers are Windows servers.
Days before, if I use following line to invoke above function for LDAP authenticate on the VIP name - ldap.mydomain.com.
For e.g.
VerifyDomainUserUsignLDAP("mydomain\\myuserid", "mypassword",
#"LDAP://ldap.mydomain.com", "SSL" ,out Message);
It always worked fine and the user was authenticated.
However, some days before, our LDAP service team made a registry change (LdapEnforceChannelBinding) on each ldap servers to
enhance the security based on MS suggestion.
In short, they changed following key value from 0 to 2
Path: HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/NTDS/Parameters
Key: LdapEnforceChannelBinding
Here is detail page about the setting on MS web site.
Use the LdapEnforceChannelBinding registry entry to make LDAP authentication over SSL/TLS more secure
https://support.microsoft.com/en-hk/help/4034879/how-to-add-the-ldapenforcechannelbinding-registry-entry
After that, I noticed my above function stop working.
i.e. if I use same line to invoke above function for LDAP authenticate.
For e.g.
VerifyDomainUserUsignLDAP("mydomain\\myuserid", "mypassword",
#"LDAP://ldap.mydomain.com", "SSL" ,out Message);
It always returned exception "Logon failure: unknown user name or password."
(I promise password and user name were correct.)
Then, I did further investigation.
I tried to use following line to invoke above function for LDAP authenticate on any individual dc server, e.g.
dcserver001.mydomain.com.
VerifyDomainUserUsignLDAP("mydomain\\myuserid", "mypassword",
#"LDAP://dcserver001.mydomain.com", "SSL" ,out Message);
It worked fine as well.
I actually tested all individual dc servers one by one, thwy were all working.
So, it looks like the ldap request with same invoke parameters works well on the individual dc server, but it doesn't work on the VIP name.
Then, I asked the ldap server team to rollback to LdapEnforceChannelBinding change to value 0. Then, I re-tested ldap against both individual server and VIP name, both worked.
I checked with our metwork team and got got some more information as follwoing.
They said this won't work with LDAPS VIPs because the SSL channel from client is terminated on F5, and reestablished to DC.
the reason why it works directly to the dc is because its one continuous packet.
The update addresses this vulnerability by incorporating support for Extended Protection for Authentication security feature, which allows the LDAP server to detect and block such forwarded authentication requests once enabled.
What I need help is - is there anyone here encountered the similar ldap ssl logon issue against F5 VIP and with the LdapEnforceChannelBinding registry value = 1 or 2?
If LdapEnforceChannelBinding registry value = 1 or 2 on the LDAP servers, what changes need to be done to resolve above LDAPS logon issue?
Thanks a lot!
Jun

Active Directory authentication in ASP.NET

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).

DNS setup Impact the AD authentication in C#

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.

Trouble Shooting Help: Active Directory Bind Fails

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.

Categories

Resources