In C#, how do I authenticate a user on a network machine?

22,930

Solution 1

If you are not using Active Directory, you could use something like this:

using System.Security;
using System.DirectoryServices.AccountManagement;
    public struct Credentials
    {
        public string Username;
        public string Password;
    }
    public class Domain_Authentication
    {
        public Credentials Credentials;
        public string Domain;
        public Domain_Authentication(string Username, string Password, string SDomain)
        {
            Credentials.Username = Username;
            Credentials.Password = Password;
            Domain = SDomain;
        }
        public bool IsValid()
        {
            using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, Domain))
            {
                // validate the credentials
                return pc.ValidateCredentials(Credentials.Username, Credentials.Password);
            }
        }
    }

If you are using Active Directory, you could use something like this:

 PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

    // define a "query-by-example" principal - here, we search for a UserPrincipal 
    UserPrincipal qbeUser = new UserPrincipal(ctx);

    // if you're looking for a particular user - you can limit the search by specifying
    // e.g. a SAMAccountName, a first name - whatever criteria you are looking for
    qbeUser.SamAccountName = "johndoe";

    // create your principal searcher passing in the QBE principal    
    PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

    // find all matches
    foreach(var found in srch.FindAll())
    {
        // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....          
    }

Solution 2

If your machines are not in a domain, you need to use ContextType.Machine:

PrincipalContext context = 
    new PrincipalContext(ContextType.Machine, exampleMachineDomain);
return context.ValidateCredentials(username, password);

Solution 3

There's a few different options presented in this answer. The snippet you pasted above should work, though.

Solution 4

The best way to do this would be to use WNetUseConnection, a Win32 API which allows for the most direct way. In effect, you're trying to call

net use \\server password /user:myUserName,

which is what this API is intended to do.

A good example of this has been answered at this question.

Because the PinvokeWindowsNetworking function returns null when successful, the simplest authentication code is

private static bool AuthenticateUserOnRemote(string server, string userName, string password)
{
    var connected = PinvokeWindowsNetworking.connectToRemote(server, userName, password);
    var disconnected = PinvokeWindowsNetworking.disconnectRemote(server);
    return connected == null;
}
Share:
22,930
Alexandru
Author by

Alexandru

"To avoid criticism, say nothing, do nothing, be nothing." - Aristotle "It is wise to direct your anger towards problems - not people; to focus your energies on answers - not excuses." - William Arthur Ward "Science does not know its debt to imagination." - Ralph Waldo Emerson "Money was never a big motivation for me, except as a way to keep score. The real excitement is playing the game." - Donald Trump "All our dreams can come true, if we have the courage to pursue them." - Walt Disney "Mitch flashes back to a basketball game held in the Brandeis University gymnasium in 1979. The team is doing well and chants, 'We're number one!' Morrie stands and shouts, 'What's wrong with being number two?' The students fall silent." - Tuesdays with Morrie

Updated on December 10, 2020

Comments

  • Alexandru
    Alexandru over 3 years

    In C#, how do I authenticate a user on a network machine? For example, I want to authenticate the user testuser with password testpassword on the machine EXAMPLEMACHINE from a different machine which is network-connected to EXAMPLEMACHINE. For example, I am on MYMACHINE and I want to authenticate testuser with testpassword on EXAMPLEMACHINE.

    I have tried the following but it keeps telling me that, The LDAP server is unavailable:

    PrincipalContext context =
        new PrincipalContext(ContextType.Domain, exampleMachineDomain);
    return context.ValidateCredentials(username, password);
    
  • Oskar Berggren
    Oskar Berggren almost 8 years
    I do not understand these examples... It says to use ValidateCredentials() when not under AD, and a regular search if it IS under AD - and the AD code doesn't even mention the user's password. What does this really accomplish?
  • MethodMan
    MethodMan almost 8 years
    Perhaps you need to understand PrincipalContext before you comment on something you should understand it's context. why write all kinds of code using AD when PrincipalContext gives you more robust functionality / access..
  • Oskar Berggren
    Oskar Berggren almost 8 years
    As I tried to imply... I'm trying to understand. Do you mean that the first example ("not using AD") is when you have a pre-AD windows domain? Or why does it work with ContextType.Domain specified if there is no AD domain? And in the second example ("using AD"), where/how does it actually verify the user? (i.e corresponding to username/password from the first example).
  • MethodMan
    MethodMan almost 8 years
    this works and you do not have to specify a specific domain perhaps you should try the example and change it to fit your use case.. the code is pretty straight forward.