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
----------------------------------------------------------
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
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
public UserProfile GetUserDetails(string Domain, string UserId)
{
var user = new UserProfile();
Logger logger = new Logger();
try
{
using (HostingEnvironment.Impersonate())
{
PrincipalContext AD = new PrincipalContext(ContextType.Domain, Domain);
UserPrincipal u = new UserPrincipal(AD);
u.SamAccountName = UserId;
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.
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