autenticating ldap for web applications - c#

please take a few minutes and read my question completely. here is my problem :
I want to connect to LDAP server by C# for a web application, means clients connecting to the asp.net server.
*- The ldap server and application server are not the same.
**- They are not in a same domain.
I have been trying 4 different ways and could not solve the problem by none of them.
1-
var credentials = new NetworkCredential(username, password);
var serverId = new LdapDirectoryIdentifier("domain.net");
var conn = new LdapConnection(serverId, credentials);
conn.Bind();
2-
System.DirectoryServices.DirectoryEntry entry = new System.DirectoryServices.DirectoryEntry("LDAP://domain.net/DC=domain,DC=net");
entry.Username = "username";
entry.Password = "password";
System.DirectoryServices.DirectorySearcher searcher = new System.DirectoryServices.DirectorySearcher(entry);
searcher.Filter = "(&(objectClass=user))";
var results = searcher.FindAll();
the problem with these 2 ways is that the user must have an access to the server for login and we know that there is only admin of the system who has the permission.
3-
PrincipalContext pc = new PrincipalContext(ContextType.Domain, "domain.net");
var ret = pc.ValidateCredentials(model.UserName, model.Password);
the problem is the server must be in the domain of ldap server. we have this limitation !!
4-
https://auth0.com/blog/using-ldap-with-c-sharp/
public bool validateUser(string username, string password)
{
var sha1 = new SHA1Managed();
var digest = Convert.ToBase64String(sha1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)));
var request = new CompareRequest(string.Format("uid={0},ou=users,dc=example,dc=com", username),
"userPassword", "{SHA}" + digest);
var response = (CompareResponse)connection.SendRequest(request);
return response.ResultCode == ResultCode.CompareTrue;
}
this code does not return any thing. it will be very helpful if there is a query to compare usernames and passwords. this code seems to use this way but there are different types of hash algorithms. I tried to use SHA1 and MD5, and userPassword , unicodePwd attribute. but the return is empty all the time.
is it the best solution to put both servers in a same domain? any other solution , Thank you so much.

Method 1 is the simplest way. If that doesn't work, nothing will. So you will have to change your configuration to make it work.
When you say:
the user must have an access to the server for login and we know that there is only admin of the system who has the permission.
What do you mean? Are you explicitly denying login rights to the domain controllers? Are there network issues between the computer this is running on and the domain controller (can you hit port 389 on the domain controller(s))?
Update: PrincipalContext.ValidateCredentials just does an LDAP bind in behind - it uses LdapConnection. You can see the source code here. The probable reason why ValidateCredentials is working on a domain machine and not otherwise is because it uses Kerberos authentication by default, which will only work from a domain computer.
The same is true with LdapConnection. So try setting the authentication mode. For example, try Basic
var credentials = new NetworkCredential(username, password);
var serverId = new LdapDirectoryIdentifier("domain.net");
var conn = new LdapConnection(serverId, credentials, AuthType.Basic);
conn.Bind();
Or look at the available values and try what works.

Related

How to keep my application "authenticated" with an AD account? c#

I am pretty new to C#
I have been using Powershell scripts to code things like Unlocking an AD user or Enabling/Disabling an account. however, I do this with a different account, so I will log in with the admin account (Get-Credential) and storing it as '$cred' for example.
I am currently trying to do a similar thing in C# and I have found how to effectively "Authenticate"
But I am not sure how to store that Authentication, or have my app Authenticated to do things with it like Disable or Unlock an AD Account.
I have this:
public bool ADauthenticate(string username, string password)
{
bool result = false;
using (DirectoryEntry _entry = new DirectoryEntry())
{
_entry.Username = username;
_entry.Password = password;
DirectorySearcher _searcher = new DirectorySearcher(_entry);
_searcher.Filter = "(objectclass=user)";
try
{
SearchResult _sr = _searcher.FindOne();
string _name = _sr.Properties["displayname"][0].ToString();
MessageBox.Show("authenticated!");
result = true;
this.Close();
}
catch
{
MessageBox.Show("Incorrect credentials");
this.ADUsername.Text = "";
this.ADPwd.Text = "";
}
}
return result; //true = user Authenticated.
}
Which just tells me that the account is correct of course, but doesn't keep my application "authenticated", any ideas?
It's not accurate to say that your "application" was authenticated. All that was authenticated is a single network connection to your domain controller. As soon as _entry is destroyed, you lose that authentication.
If you want everything to happen using those credentials, then you have several options, ranging from easy (for you) to more difficult:
Have your users run your application under the credentials they need. Then you don't need to bother getting their username and password or setting the username and password on the DirectoryEntry object. Users can do this by:
Using Shift + right-click on the application icon and click "Run as a different user", or
Create a shortcut to: runas.exe /user:DOMAIN\username "yourapplication.exe". This will open a command window asking for the password, then start your application under those credentials.
You still ask for the username and password, but restart your application under those credentials using Process.Start().
Keep the username and password variables alive for the life of the application and pass them to every DirectoryEntry object you create in your application.
Options 1 and 2 require the computer that you're running this from is joined to the same or trusted domain as the domain you are connecting to. But since I see you're not specifying the domain name, I'm guessing that's the case.
You can do this a lot easier by using the System.DirectoryServices.AccountManagement assembly and namespace.
Add a reference to the System.DirectoryServices.AccountManagement assembly to your project, and then use this code to validate username/password against AD:
using System.DirectoryServices.AccountManagement;
// create the principal context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YourDomain"))
{
bool accountValidated = ctx.ValidateCredentials(userName, password);
// do whatever you want to do with this information
}

Problems with LDAP

I am having trouble with LDAP. Now I use this code:
DirectoryEntry ldapConnection = new DirectoryEntry("LDAPS://*******.com:636", "User#bloom.local", "Password");
ldapConnection.AuthenticationType = AuthenticationTypes.SecureSocketsLayer;
DirectorySearcher search = new DirectorySearcher(ldapConnection);
var result = search.Filter = "(objectClass=*)";
search.FindAll();
I spent a large number of experiments, but never received:
Unknown error (0x80005000)
or
The server is not operational.
My property in the softerra LDAP Administrator:
The problem is that the simple authentication mechanism requires an LDAP distinguished name (DN) and you provided just a user name. At least, this is what your screenshot shows.
The DN of the administrator is likely something like cn=Administrator,cn=Users,dc=bloom,dc=local.
Also, I would probably steer away from using the administrator credentials in production. It is much more preferable to create an account with the right privileges.

how to secure password during ldap connection

I have developed an mvc application where I am using ldap authendication to validate the user.
I need some help to secure my password during ldap connection. I have tried Securesocketlayer=true but I guess it need certificate. Its giving an error:
handshake failure ssl.
Here is my code. I am getting a comment from my security team User credentials are sent in clear text over the network for authentication.
Can anyone help me on how to achieve this in ldap?
Here is my code:
using LdapConnection = Novell.Directory.Ldap.LdapConnection;
using LdapException = Novell.Directory.Ldap.LdapException;
var ldapHost = WebConfigurationManager.AppSettings["LDAP_HOST"];
var ldapPort = WebConfigurationManager.AppSettings["LDAP_PORT"];
var connection = new LdapConnection {SecureSocketLayer = true};
connection.Connect(ldapHost, Convert.ToInt32(ldapPort));
sb = new StringBuilder();
sb.Append(ldapLocation).Append(userName).Append(",").Append(ldapLocationIndia);
connection.Bind(LdapConnection.Ldap_V3, sb.ToString(), password);
Thanks in advance

Obtain Network Credentials from Current User in Windows Authentication Application

I was wondering whether it was possible to obtain the current user object and get their credentials so that I can pass them along to a NetworkCredential object which I am using to connect to my AX .NET Business Connector. As, at the moment I'm having to specify it connect as a specific user which I set when I instantiate a NetworkCredential object:
private NetworkCredential nc = new NetworkCredential("myUser", "myPassword", "myDomain");
I was hoping to do something like: private NetworkCredential nc = (NetworkCredential)HttpContext.User; but obviously that won't work...
That way, it's easier to keep track of which user has created a sales order for example, as at the moment everything gets created by the user I have specified..
CredentialCache.DefaultNetworkCredentials?
The credentials returned by DefaultNetworkCredentials represents the authentication credentials for the current security context in which the application is running. For a client-side application, these are usually the Windows credentials (user name, password, and domain) of the user running the application.
I don't fully understand your question, but is your call coming from ASP.NET that you require the credentials? You could attempt:
Uri uri = new Uri("http://tempuri.org/");
ICredentials credentials = CredentialCache.DefaultCredentials;
NetworkCredential credential = credentials.GetCredential(uri, "Basic");
Assuming your user has already authenticated via a Membership Provider.
A combination of the above worked great for me to resolve the authentication.
var credentials = new NetworkCredential();
ICredentials credent = CredentialCache.DefaultNetworkCredentials;
credentials = (NetworkCredential)credent;
var serverId = new LdapDirectoryIdentifier(GlobalVariables.LDAPServer);
LdapConnection connection = new LdapConnection(serverId, credentials);
connection.Bind();

C#/.NET: How to access a network printer share with another user's credentials?

In Windows, when using a local PC account and trying to access the network printer share (ie typing "\printershare" in the Run window), a box pops up asking for a domain user's username and password.
Put in a domain user's username and password, and then the printer share appears using the domain user's credentials.
How can this be achieved via C#?
I have tried the following methods:
var printerShare = new DirectoryEntry(#"\\printershare\", "username", "password");
var printerShare = new DirectoryEntry(#"WinNT://printershare\", "username", "password");
var printerShare = new DirectoryEntry(#"WinNT:\\printershare\", "username", "password");
var printerShare = new DirectoryEntry("LDAP://printershare.corp.domain.com", "username", "password");
var printerShare = new DirectoryEntry("LDAP:\\printershare.corp.domain.com", "username", "password");
Unfortunately, none of them work. Mapping a network directory or folder would be simple.
But the fact that there are no folders is what is making me scratch my head.
Anyone know what I'm doing wrong here?
Check out this question (specifically the NetworkConnection class):
How to provide user name and password when connecting to a network share

Categories