Authenticate against a domain using a specific machine? - c#

Background
We are transitioning to Claims-Based auth in our app (on .NET 4.5)
We currently have authentication via Asp.net membership & domain auth working correctly.
The domain portion looks like this (generalized a little):
var context = new PrincipalContext(ContextType.Domain, ADDomainName);
return context.ValidateCredentials(username, password);
Problem / Goal
Sometimes we (or some consultants we use) are on a VPN connection using machines that can see our domain servers, but that aren't members of our domain.
It would be a great help to test the app from a machine that isn't on the domain, rather than having to fire up a machine that is on the domain in order to check.
Question
Is there a way to perform domain authentication against a domain controller from a machine that isn't on the domain? I haven't been able to find any research on it thus far.

You can use LDAP authentication and specify credentials from your code:
using(var context = new PrincipalContext(ContextType.Domain, "mydomain", #"mydomain\serviceAcct", "serviceAcctPass"))
{
//Username and password for authentication.
return context.ValidateCredentials(username, password);
}
Or, run your authenticating server under runas /netonly, which lets you run with domain network credentials from a workgroup joined computer
rem if your server is standalone
runas /netonly /user:mydomain\consultantaccount C:\dev\sts\ipsts.exe
rem or you can have it in IIS Express:
runas /netonly /user:mydomain\consultantaccount "iisexpress /path:c:\dev\sts\ /port:9090 /clr:v2.0"
I will note that I have not actually checked whether /netonly will work in this context, so if you end up trying it, I'd be interested to hear if it worked.

Related

How to run application in an authenticated manner

I've created a small application which attempts to authenticate a user based on their username and password. This application works correctly when run on the same domain which Active Directory resides on.
I must now extend the application to also work on domains which are "closed" in terms of security and permissions. In other words, is there a way to run the application based on an administrator account, or an account which has the necessary permissions to access the Active Directory?
This is the code I have used to authenticate a user:
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, server + ":" + port))
{
if (pc.ValidateCredentials(username, password))
{
valid = true;
}
else
{
valid = false;
}
}
The above code works perfectly, however I would like to modify it so that it can communicate with the Active Directory database in an authenticated manner.
I have read numerous documentation and resources, but have not found anything. The closes I found was an article mentioning that IIS has to be set up and configured in a specific manner. However, my application is a simple C# application, and IIS is not being used.
If I understand the question properly, you want to execute ValidateCredentials using a different user than the current process' user.
I may be missing something, but have you tried modifying your code this way?
using (PrincipalContext pc =
new PrincipalContext(ContextType.Domain,
server + ":" + port,
specialAccountUsername,
specialAccountPassword))
{
return pc.ValidateCredentials(username, password);
}
It simply uses a constructor that takes the special account you are using for accessing the domain.

login with active directory autentication in asp.net c#

I am creating the asp.net web application. In that I used active directory for login. I have one group named Validusers, when user logged in it checks the user to that validusers group. If the user exists in the group then login is successful, if not login failed.
I did all the things, it works good in my local machine, but it is not working when I publishing the website. I got the following error
Logon failure: unknown user name or bad password.
On my machine it works good,while publishing i got an error.i used below code for your reference
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "DomainName");
System.Security.Principal.WindowsIdentity MyIdentity = System.Security.Principal.WindowsIdentity.GetCurrent();
string LogUser = MyIdentity.Name.ToString();
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, LogUser);
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "Validusers");Validusers---->Groupname
if (user.IsMemberOf(group))
{
Login success
}
else
{
Login Failed
}
it will check logged user with Validusers group.if the user exists in the group then login is success other wise failed login. I got an error when i published this website.please give some solution
Although you had supplied so little information about the domain and network relationship with your development machine and web server, I assume the web server has no physical connection to the Active Directory server that you depend your code on. Then it should be impossible for web server to query the AD directory.
If web and AD servers are on same network than you may need to work on the firewall settings of both web server and AD server to make sure that they can communicate.
If web and AD server have no communication problems you should check the availability of that "Validusers" to a code running at web server.
As IIS applications run with the user account that is defined for the application pool that hosts the application, you should make sure that the app pool identity has enough rights to access those delicate information.

C# check if two computers are in a trusted domain (or: decide which authentication mechanism for winrm connection)

I want to connect via winrm to other computers. I got only the FQDN of the destination computer which i want to connect. I have no information of the destination whether it is in a trusted Domain.
So the basic question is how do i now which Authentication mechanism is needed to connect?
Are there any C# .NET methods to check that?
Or is the easier way to set the authentication mechanism to kerberos, and if it fails set it to negotiate?
WSManConnectionInfo wci = new WSManConnectionInfo(TargetUri, ShellUri.ToString(), Credential);
wci.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
There is the solution
http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/0a5cb5a4-317c-4fcd-9221-85884af1217f
//Trusts for current domain
Domain currentDomain = Domain.GetCurrentDomain();
var domainTrusts = currentDomain.GetAllTrustRelationships();

How does PrincipalContext login to domain server

I have the following C# code that connects to my domain server and performs some actions on it. Everything works fine on my computer and I can run all my commands just fine.
My questions is: what credentials are used for the connection to the server? I assume it uses the current users credentials. So my real question is will this work on a normal user. I am an admin and it works fine on my machine.
However I am wondering if the same would hold true for a non admin?
PrincipalContext AD = new PrincipalContext(ContextType.Domain, "172.18.4.4");
UserPrincipal u = new UserPrincipal(AD);
u.SamAccountName = Environment.UserName;
PrincipalSearcher search = new PrincipalSearcher(u);
UserPrincipal result = (UserPrincipal)search.FindOne();
If that code is running in a Windows app then the credentials used are the ones of the current Windows user and it should work fine in a domain. If the code is running in an ASP.NET site, then the credentials are the ones of the application pool in which the site is running. In this last case, you might need to play with the Identity of the app pool: LocalSystem, NetworkService...
In any of the previous cases, you can impersonate a user to run this code under: (look at the answer)
How to use LogonUser properly to impersonate domain user from workgroup client

Change remote password (in code, .Net 3.5)

Due to our clients authentication and network topology we have a number of Windows Servers in a DMZ without Active Directory or a Domain Controller. Corporate policy stipulates that passwords must change once a month. Our dev machines are in AD (not in the DMZ) so we run into the situation that we have to synchronise our usernames and passwords on each of the DMZ machines with our AD credentials every month. There are a lot of DMZ machines.
I want to use a simple console app to change the user passwords on all the DMZ machines for a given user. So far, I have the following code:
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
class Program{
static void Main(){
List<string> remoteHosts = new List<string> { "RemoteHostA", "RemoteHostB", "RemoteHostC" };
remoteHosts.ForEach(host => ChangePassword(host, "username", "oldPassword", "newPassword"));
}
static void ChangePassword(string host, string username, string oldPassword, string newPassword){
using (var context = new PrincipalContext(ContextType.Machine, host, username, newPassword))
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username))
user.ChangePassword(oldPassword, newPassword);
}
}
The problem is that this only works if the password has not already changed on the dev machine where it is being run from. Because the context that is used, first has to authenticate with the dev machine in order to gain access to the network, then it has to gain access to the remote (DMZ) machine using the same context before changing the password.
How can I alter the method to use a new-password-context to gain access to the network and an old-password-context to gain access to the remote host?
Note to Title Editors: The code depends on System.DirectoryServices.AccountManagement which is an FX 3.5 assembly not 3.0.
Can you use WMI directly to achieve this? A quick search showed up this page
Note : It is a long time since I did anything with WMI, but I do remember being able to call it from a C# app, if that's how you are comfortable using it. (Check in System.Management)

Categories