User entering username and password for login in project. But customer want passwordless login with windows authenticated for every employee. I changed authentication mode from anonymous authentication to windows authentication. Now required windows authenticated before the application run.But entering the windows credential same username and password every time, which containing project published in iis.
Question 1. How i do required only client windows username and password in windows authentication?
Assuming i used client windows username and password for authentication. IsAuthenticated = true;
Here my new question.
Question 2. How i do catch client windows username?
Now use 2 different way for catch windows username.
Way 1.
var name = _username.HttpContext.User.Identity.Name;
var isactive = _username.HttpContext.User.Identity.IsAuthenticated;
return $"name: " + name + " | IsAuthenticated: " + isactive;
Return this -> name: URCTEST01\Ziya Mammadov | IsAuthenticated: True
Way 2.
WindowsIdentityHelper wih = new WindowsIdentityHelper();
var name = wih.GetLoginUserName();
return name;
public class WindowsIdentityHelper
{
public WindowsPrincipal GetWindowsPrincipal()
{
//Get Current AppDomain
AppDomain myDomain = Thread.GetDomain();
myDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
return (WindowsPrincipal)Thread.CurrentPrincipal;
}
public bool IsUserBelongsToWindowsAdministratorGroup()
{
WindowsPrincipal myPrincipal = GetWindowsPrincipal();
if (myPrincipal.IsInRole("Administrators"))
return true;
if (myPrincipal.IsInRole(WindowsBuiltInRole.Administrator))
return true;
else
return false;
}
public string GetFullDomainLoginUserName()
{
WindowsPrincipal myPrincipal = GetWindowsPrincipal();
return myPrincipal.Identity.Name.ToString();
}
public string GetLoginUserName()
{
string authenticatedUser = string.Empty;
string userName = GetFullDomainLoginUserName();
authenticatedUser = userName;
return authenticatedUser;
}
}
Return this -> IIS APPPOOL\timesheet
Way 1 return username which windows contain project.
Way 2 return IIS APPPOOL.
How to catch correct username?
Related
I have one website designed in ASP.NET MVC 5 hosted with website name of www.oldsite.com.
We just now started a new website - www.newsite.com with some changes to the ASP.NET MVC code and but database is the same for both sites.
When a user logs in to the old website, www.oldsite.com verifies the login details (userid and password) and after successful login redirects the user based on some condition to new website www.newsite.com with automatic login (user does not need to re-enter userid and password in login page again on www.newsite.com) and shows the home page of www.newsite.com.
This is my code
int timeout = login.RememberMe ? 600 : 60; // 525600 min = 1 year
var ticket = new FormsAuthenticationTicket(v.PEmailId, login.RememberMe, timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
cookie.Expires = DateTime.Now.AddMinutes(timeout);
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
if (some condition)
{
return Redirect("www.newsite.com");
}
I need some login authentication cookies code, I am using ASP.NET identity.
Please tell me how to redirect from old site to new site www.newsite.com with login credentials (give like userid and password parameter in login page and automatically login into new website) or how to create cookies for new website www.newsite.com for automatic login without entering userid and password.
Thank you
From old site you can pass the username and password as parameter.
return Redirect(string.Format("https://newsite.com/Home/Index?username={0}&password={1}","username", "password"));
In new site create a function that allow anonymous users. Then validate the user credential. If the user is valid one then add cookies and redirect to the page you want.
[AllowAnonymous]
public class HomeController : Controller
{
public ActionResult Index(string username, string password)
{
// validate the user credential
// add cookie
User user = new User();
user.UserName = username;
user.Password = password;
AddCookie(user);
return RedirectToAction("Index", "Dashboard");
}
public void AddCookie(User user)
{
string encryptTicket, userData;
HttpCookie httpCookie = null;
try
{
userData = JsonConvert.SerializeObject(user);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, user.UserName, DateTime.Now, DateTime.Now.AddHours(1), true, userData, FormsAuthentication.FormsCookiePath);
encryptTicket = FormsAuthentication.Encrypt(ticket);
httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptTicket);
Response.Cookies.Add(httpCookie);
}
catch (Exception exception)
{
}
return httpCookie;
}
}
public class User
{
public string UserName { get; set; }
public string Password { get; set; }
}
I am trying to query LDAP server for a valid credential (username and password).
The problem is eventhough the credential itself is registered in the server it doesn't get authenticated.
If i put old ldapPath it works fine.
The code is running on visual studio development server on my local machine (Not IIS).
Whenever i run this i get "Directory Services Com Exception.
Logon failure: unknown user name or bad password.".
const string ldapPath="LDAP:\\newDomain"; //please note this is just an example
public override bool ValidateUser(string username, string password)
{
DirectoryEntry directoryEntry = new DirectoryEntry(ldapPath, username, password, AuthenticationTypes.ServerBind);
DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry)
{
SearchScope = SearchScope.Subtree,
Filter = "uid="+username
};
try
{
using(HostingEnvironment.Impersonate())
{
SearchResult resultEmployee = directorySearcher.FindOne();
return resultEmployee.Properties["uid"].Count == 1;
}
}
catch (DirectoryServicesCOMException)
{
return false;
}
}
I want to know if there's a way to validate domain credential and make sure we don't use the Cached Domain Credential ?
I use this to validate the credential :
bool valid = false;
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
valid = context.ValidateCredentials( username, password );
}
The problem is when I change the password, the old password is still working.
EDIT : If you force the password to be reset, the cached domain credential will not be use. But between the moment we force the reset, and moment the user reset the password, the old password will still work.
Question already has an answer Why does Active Directory validate last password?
Solution is to use a Kerberos authentication.
The following code shows how you can perform credential validation using only Kerberos. The authentication method at use will not fall back to NTLM in the event of failure.
private const int ERROR_LOGON_FAILURE = 0x31;
private bool ValidateCredentials(string username, string password, string domain)
{
NetworkCredential credentials
= new NetworkCredential(username, password, domain);
LdapDirectoryIdentifier id = new LdapDirectoryIdentifier(domain);
using(LdapConnection connection = new LdapConnection(id, credentials, AuthType.Kerberos))
{
connection.SessionOptions.Sealing = true;
connection.SessionOptions.Signing = true;
try
{
connection.Bind();
}
catch (LdapException lEx)
{
if (ERROR_LOGON_FAILURE == lEx.ErrorCode)
{
return false;
}
throw;
}
return true;
}
you might try something like this
try
{
using (var directoryEntry = new DirectoryEntry(ldapPath, userName, password))
{
var invocation = directoryEntry.NativeObject;
return true;
}
}
catch (Exception ex)
{
return false;
}
I am using the standard Simple Membership model for login via forms in my application. I would like to provide the possibility to login via AD as an alternative.
When logging in via AD, the process should be as follows:
Check that AD authenticates the user, but do not use the information for the principal.
Check if any local user exists with the provided Active Directory username (I have a property on my UserProfile model named ActiveDirectoryID).
If it exists, perform a local login using the local username for this UserProfile.
The problem: I cannot retrieve the local password, so in order to login locally after AD authentication, I need to be able to force the login without the password.
I've considered the following strategies:
Create an extension method for Websecurity to allow Websecurity.Login(string username)
Somehow set the logged in user manually, without implicating Websecurity.
Is this doable / feasible? Is it possible for the framework to create the necessary auth cookie without the plaintext password? And how would I do this?
SOLUTION:
This ended being the correct solution:
public ActionResult ActiveDirectoryLogin(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
try
{
DirectoryEntry entry = new DirectoryEntry("LDAP://DC=MyIntranet,DC=MyCompany,DC=com", model.UserName, model.Password);
object NativeObject = entry.NativeObject;
var internalUser = db.UserProfiles.Where(x => x.ActiveDirectoryID == model.UserName).SingleOrDefault();
if (internalUser != null)
{
FormsAuthentication.SetAuthCookie(internalUser.UserName, model.RememberMe);
return RedirectToLocal(returnUrl);
}
}
catch (DirectoryServicesCOMException)
{
// No user existed with the given credentials
}
catch (InvalidOperationException)
{
// Multiple users existed with the same ActiveDirectoryID in the database. This should never happen!
}
}
return RedirectToAction("Login");
}
This is all that the Websecurity.Login method does:
public static bool Login(string userName, string password, bool persistCookie = false)
{
WebSecurity.VerifyProvider();
bool flag = Membership.ValidateUser(userName, password);
if (flag)
{
FormsAuthentication.SetAuthCookie(userName, persistCookie);
}
return flag;
}
You can write your own method that authenticates against AD and then looks up the user name and the does sets the auth cookie something like:
public static bool MyLogin(string userName, string password, bool persistCookie = false)
{
bool flag = CheckADUser(userName, password);
if (flag)
{
string mappedUsername = GetMappedUser(userName);
if(mappedUsername != "")
{
FormsAuthentication.SetAuthCookie(userName, persistCookie);
}
else
{
flag = false;
}
}
return flag;
}
Hope this helps.
I'm dealing with two domains - one is a trusted domain. There may be a JohnSmith on one domain and another JohnSmith on the other. Both of these people need to log into my application.
My problem: it doesn't matter which domain I pass in - this code returns true! How do I know which JohnSmith is logging in?
static public bool CheckCredentials(
string userName, string password, string domain)
{
using (var context = new PrincipalContext(ContextType.Domain, domain))
{
return context.ValidateCredentials(userName, password);
}
}
The ValidateCredentials works with userPrincipalName you perhaps can try to build the first parameter (username) combining the login and the domain to create the username JohnSmith#dom1.com versus JohnSmith#dom2.com.
You can always retrieve the full DN of the user who has logged in using
UserPrincipal up = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, userName);
up.UserPrincipalName // shows user#domain.com
up.DistinguishedName // shows CN=Surname,OU=group,DC=domain,DC=com
up.SamAccountName // shows login name
Use the up.SamAccountName to subsequent calls to ValidateCredentials including the domain name - you can't have 2 users who log in using the same sAMAccountName after all!
The DistinguishedName will definitely show you which JohnSmith logged in.
Based on JPBlanc's answer, I've re-written my code. I've also added a try/catch in case a bogus domain is passed in.
static public bool CheckCredentials(
string userName, string password, string domain)
{
string userPrincipalName = userName + "#" + domain + ".com";
try
{
using (var context = new PrincipalContext(ContextType.Domain, domain))
{
return context.ValidateCredentials(userPrincipalName, password);
}
}
catch // a bogus domain causes an LDAP error
{
return false;
}
}
The accepted answer will fail with Domains that contain different email addresses within them. Example:
Domain = Company
User1 = employee#department1.com (under company Domain)
User2 = employee2#Department2.com (under company Domain)
The provided answer will return false using:
userName = "employee";
domain = "company";
string userPrincipalName = userName + "#" + domain + ".com";
The correct way to encompass users across domains is:
string userPrincipalName = userName + "#" + domain;
without the .com portion it searches the user AT that domain instead of searching for an email within a global domain.