views:

332

answers:

1

I have an intranet server on a Windows domain (server is Windows 2003, IIS6, NTFS permissions). It is on the domain Domain01. I have users from two domains in the same forest that access this intranet: Domain01 and Domain02 (DCs also running Windows 2003). Currently, the users are required to login by entering either: Domain01\username or username@Domain01

My users are completely and thoroughly confused by having to enter the domain each time they log in. Is there any way to simply allow them to log in by entering just their username and password WITHOUT the domain? For example, have the server try Domain01 by default, and if the login fails to try Domain02?

NOTE: I would like to do this via IIS or server settings if possible, rather than programmatically (for reference, I am using ASP.NET 2.0).

+1  A: 

Yes. Usually what I do is do a global catalog search using the supplied user name as the sAMAccountName. Doing this with a PrincipalSearcher requires getting the underlying DirectorySearcher and replacing it's SearchRoot. Once I find the corresponding user object I extract the domain from the user object's path and use that as the domain for the authentication step. How you do the authentication varies depending on what you need it to do. If you don't need impersonation you can use PrincipalContext.ValidateCredentials to make sure that the username/password match using a PrincipalContext that matches the domain of the user account that you previously found. If you need impersonation check out this reference.

// NOTE: implement IDisposable and dispose of this if not null when done.
private DirectoryEntry userSearchRoot = null;
private UserPrincipal FindUserInGlobalContext( string userName )
{
    using (PrincipalSearcher userSearcher = new PrincipalSearcher())
    {
        using (PrincipalContext context
                 = new PrincipalContext( ContextType.Domain ))
        {
            userSearcher.QueryFilter = new UserPrincipal( context );
            DirectorySearcher searcher
                 = (DirectorySearcher)userSearcher.GetUnderlyingSearcher();

            // I usually set the GC path from the existing search root
            // by doing some string manipulation based on our domain
            // Your code would be different.
            string GCPath = ...set GC path..

            // lazy loading of the search root entry.  
            if (userSearchRoot == null)
            {
                userSearchRoot = new DirectoryEntry( GCPath );
            }

            searcher.SearchRoot = userSearchRoot;
            using (PrincipalContext gcContext =
                     new PrincipalContext( ContextType.Domain,
                                           null,
                                           GCPath.Replace("GC://",""))
            {
                UserPrincipal userFilter = new UserPrincipal( gcContext );
                userFilter.SamAccountName = userName;
                userSearcher.QueryFilter = userFilter;
                return userSearcher.FindOne() as UserPrincipal;
            }
        }
    }
}
tvanfosson