Directory Programming .NET

Active Directory and ADAM programming support for .NET developers
Welcome to Directory Programming .NET Sign in | Join | Help
in Search

Using a Service Account with AccountManagement

Last post 03-02-2011, 4:15 PM by gearhead. 9 replies.
Sort Posts: Previous Next
  •  02-18-2011, 12:22 PM 8875

    Using a Service Account with AccountManagement

    What is the standard way to use a “Service Account” with AccountManagement? We want to have a single fixed account that we use to connect to our LDAP server, then use that connection to check the validity of our normal user accounts. It seems to be easy enough to check the user’s name, but not so easy to check the password; does anyone know how to do this?

    Here is what I am thinking.

    I assume that I should create the PrincipalContext with the Service account thus:

    var pc = new PrincipalContext(contextType, domain, ServiceAccountName, ServiceAccountPassword);

    Unfortunately ValidateCredentials() does not seem to be the answer. I have discovered that if I try to validate the end user’s credential, it seems to ignore the service credentials:

    bool valid = pc.ValidateCredentials(EndUserName, EndUserPassword);

    So I tried FindByIdentity() and this seems to work very nicely:

    UserPrincipal tempUser = UserPrincipal.FindByIdentity(pc, EndUserName);

    However this does not check the password. What would you suggest?

    I have tried setting the password in this tempUser and trying PrincipalSearcher but this always fails to find the account.

    Suggestions?
  •  02-18-2011, 2:49 PM 8876 in reply to 8875

    Re: Using a Service Account with AccountManagement

    The most common way of doing this is to configure your application pool thread to run as the service account (which does not have to have any special permissions). Then in your code, you can attempt to bind to the directory using the credentials supplied by the user.

    This does not use AccountManagement, but you don't really need to use that namespace specifically to do this.
  •  02-18-2011, 3:35 PM 8878 in reply to 8876

    Re: Using a Service Account with AccountManagement


    Wow; using this technique I would not have to change my code (my code already works without a service account using ValidateCredentials), just configure the pool. Very interesting.

  •  02-21-2011, 10:25 AM 8879 in reply to 8876

    Re: Using a Service Account with AccountManagement

    gearhead:
    The most common way of doing this is to configure your application pool thread to run as the service account (which does not have to have any special permissions). Then in your code, you can attempt to bind to the directory using the credentials supplied by the user.

    This does not use AccountManagement, but you don't really need to use that namespace specifically to do this.


    Dear GearHead,

    This sounds like a great approach, but our customer seems to want us to use the Service Account in our code. He seems to think that we can embed the Service Account username & password in a string that is passed to LDAP. He believes there is a standard format in which the string passed to LDAP is used each time an application does a lookup against our LDAP tree, and this service account information can be passed within this string, similar to a database call string with account credentials. Does this would familiar?

    This would all be straightforward in AccountManagement if Validate Credentials behaved correctly, but it appears that it ignores the username and password in the PrincipalContext….
  •  02-24-2011, 11:34 AM 8886 in reply to 8875

    Re: Using a Service Account with AccountManagement

    Our customer insisted on us doing this:

    1) Connect with the service account credentials
    2) Find the end user and grab his DN
    3) Attempt to bind using this DN

    So I used a mixture of AccountManagement and DirectoryServices to do this:


    pc = PrincipalContext(_contextType,
    _domain, serviceAccountName,
    serviceAccountPW);

    UserPrincipal user = UserPrincipal.FindByIdentity(
    pc,
    endUsername);


    // Get the underlying DirectoryEntry. The
    // DirectoryEntry gets loaded with the DN…

    DirectoryEntry directoryEntry =
    (DirectoryEntry)user.GetUnderlyingObject();

    directoryEntry.Password = password;



    try

    {

    // Force bind to see if password works

    object tmp = directoryEntry.NativeObject;

    }

    catch..



    Does this look about right?


    I may enhance it for FCB when I get a chance….
  •  02-25-2011, 3:12 PM 8890 in reply to 8879

    Re: Using a Service Account with AccountManagement

    You can specify credientials when you construct a directory entry object. Perhaps that is what he is referring to?

    You can do it all in code, I just find it easier to just let the thread run as the identity. Less keystrokes and you don't have to hard code anything or keep a config file somewhere that exposes the password.
  •  02-25-2011, 3:33 PM 8891 in reply to 8886

    Re: Using a Service Account with AccountManagement

    If you were running the app pool thread as the service account, you could do something like this:

    private string authenticateUser(string username, string password)
    {
    //This function returns nothing when the bind is successful
    DirectoryEntry rootde = new DirectoryEntry("LDAP://" + new DirectoryEntry("LDAP://RootDSE").Properties("defaultNamingContext").Value.ToString);
    DirectorySearcher ds = new DirectorySearcher(rootde);
    using (ds) {
    ds.Filter = "sAMAccountName=" + username;
    SearchResult result = ds.FindOne;
    if ((result != null)) {
    string dn = result.Properties("distinguishedName").Item(0).ToString;
    try {
    DirectoryEntry de = new DirectoryEntry("LDAP://" + dn.ToString(), username, password);
    object obj = de.NativeObject;
    //success
    return null;
    } catch (Exception ex) {
    //return the exception to notify bind failure
    return ex.Message;
    }
    } else {
    //Not found
    return "Invalid Username";
    }
    }
    }

    However, if you need to use the service account creds in code, which I think is a bad idea, just add the service account creds in the rootde constructor.
  •  02-25-2011, 3:35 PM 8892 in reply to 8891

    Re: Using a Service Account with AccountManagement

    Also, I'm a vb guy and I put this through a translator lol. Syntax tends to get messed up sometimes by the converters, but you should get the idea....
  •  03-02-2011, 3:27 PM 8899 in reply to 8891

    Re: Using a Service Account with AccountManagement


    I punted trying the get the service account creds in the code. Instead I used the standard AccountManagement VerifyCredentials, etc. and ran the app pool thread as the service account (making sure that the service account is a member of IIS_IUSRS). This worked beautifully and my application code (AccountManagement) is very simple.
  •  03-02-2011, 4:15 PM 8900 in reply to 8899

    Re: Using a Service Account with AccountManagement

    Cool, glad you got it working.
View as RSS news feed in XML