Click here to Skip to main content
15,889,281 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am developing a Intranet web-Application. The requirement is to build the application using Single Sign On(SSO). For that I implemented Windows Authentication & I am fetching the User Details from the active Directory by passing the User Domain & UserId of the User received after Windows Authentication.

Getting the UserId & Domain after Windows Authentication
----------------------------------------------------------
C#
void Session_Start(object sender, EventArgs e)
        {
            Logger logger = new Logger();
            logger.LogMessage("Creating Session for User- " + User.Identity.Name);
            SessionManager.CreateUserSession(User.Identity.Name);
            
            
        }


In the Create User Session Method Below I am calling the GetUserDetails method in the Authentication Manager Class

C#
public class SessionManager
    {
        public static void CreateUserSession(string ClientWindowsId)
        {
            Logger logger = new Logger();
            UserProfile user = new UserProfile();
            AuthenticationService authenticationManager = new AuthenticationService();
            string userId = ClientWindowsId.Contains("\\") ? ClientWindowsId.Split(new String[] { "\\" }, StringSplitOptions.None)[1] : ClientWindowsId;
            string domain = ClientWindowsId.Contains("\\") ? ClientWindowsId.Split(new String[] { "\\" }, StringSplitOptions.None)[0] : "INS";
            logger.LogMessage("User Id: " + userId);
            logger.LogMessage("Domain: " + domain);
            user = authenticationManager.GetUserDetails(domain, userId);
            HttpContext.Current.Session.Add("UserApplicationRole", user.UserApplicationRole);
            HttpContext.Current.Session.Add("FirstName", user.FirstName);
            HttpContext.Current.Session.Add("LastName", user.Lastname);
            HttpContext.Current.Session.Add("MiddleName", user.MiddleName);
            HttpContext.Current.Session.Add("DisplayName", user.UserDisplayName);            
        }
}


The Below method in Authentication Manager calls the ActiveDirectory to get the User Details

C#
public UserProfile GetUserDetails(string Domain, string UserId)
        {
            var user = new UserProfile();
            Logger logger = new Logger();

            try
            {

                using (HostingEnvironment.Impersonate())
                {
                    
                    //Find Users from a Domain
                    PrincipalContext AD = new PrincipalContext(ContextType.Domain, Domain);
                    UserPrincipal u = new UserPrincipal(AD);
                    u.SamAccountName = UserId; //For Finding a Particular user
                    PrincipalSearcher search = new PrincipalSearcher(u);

                    foreach (UserPrincipal result in search.FindAll())
                    {
                        
                        if (result != null)
                        {
                            
                            DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
                            if (de.Properties["samAccountName"].Value.ToString() == UserId)
                            {
                                
                                user.FirstName = de.Properties["givenName"].Value.ToString();
                                user.Lastname = de.Properties["sn"].Value.ToString();
                                user.FunctionalRole = de.Properties["Role"].Value != null ? de.Properties["LION-MonitorRole"].Value.ToString() : string.Empty;
                                user.Email = de.Properties["mail"].Value.ToString();
                                user.SAMAccountName = de.Properties["samAccountName"].Value.ToString();
                                user.UserPrincipalName = de.Properties["userPrincipalName"].Value.ToString();
                                user.UserDisplayName = de.Properties["displayName"].Value.ToString();
                            }
                        }
                    }
                }
                user.UserApplicationRole = getMappedApplicationRole(user.FunctionalRole);

            }
            catch (Exception ex)
            {
                logger.LogException(ex, ex.InnerException);
                Console.Write(ex.Message);
                throw;

            }

            return user;

        }


Every thing is working fine when i am running the Application from Visual Studio, but when i am deploying the code in IIS, the Application is not able to find out the User Details from Active Directory. It's throwing the below Exception from the GetUserDetails method of Authentication Manager Class.
C#
System.Runtime.InteropServices.COMException (0x8007052e): Logon failure: unknown user name or bad password.


Please suggest how this issue can be solved. Thanks in Advance.

What I have tried:

I have tried for impersonation using the HostingEnvironment.Impersonate()
&
WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
WindowsImpersonationContext impersonatedUser = newId.Impersonate();

but all in-vain
Posted
Comments
Kornfeld Eliyahu Peter 9-May-16 7:17am    
Check who's running IIS...Probably the account has no rights to access AD...
Umesh2014 9-May-16 7:49am    
In my system from my account only i have hosted the application in IIS? Is there any way to check that if it is not connecting the AD from my account?
Nathan Minier 9-May-16 9:17am    
Setup a service account with specific read rights in your directory, and assign the app pool to operate under that account. Make sure that account has access to the folder where your application lives.

Right now you're just impersonating either Networkservice or your AppPoolIdentity, which will not have any domain rights. If you run under a service account context you will not need to impersonate anything.
Umesh2014 9-May-16 10:47am    
Thank you very much :) That worked. Thanks a lot.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900