We have an internal facing (C#/MVC/IIS7) application for which the requirement is for users to not have to enter credentials, but we need the network/Windows username to identify who the current user is.
Is there any way to accomplish this? Thanks!
Here's some code that deals with that kind of thing:
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();
if (userName.Contains("\\"))
authenticatedUser = userName.Split('\\')[1];
else
authenticatedUser = userName;
return authenticatedUser;
}
}
This works for me (ASP.NET C#):
string username = Request.LogonUserIdentity.Name;
Related
So i want to create a new user and give it admin rights but i also need it to change the PasswordNeverExpires option to true.
class Program
{
public static string Name;
public static string Pass;
static void Main(string[] args)
{
Name = "Test1";
Pass = "Test2";
createUser(Name, Pass);
}
public static void createUser(string Name, string Password)
{
try
{
using (PrincipalContext ctx = new PrincipalContext(ContextType.Machine))
{
// create new newUser
UserPrincipal newUser = new UserPrincipal(ctx);
// set some properties
newUser.SamAccountName = Name;
newUser.SetPassword(Password);
// define new newUser to be enabled and password never expires
newUser.Enabled = true;
newUser.PasswordNeverExpires = true;
// save new newUser
newUser.Save();
Console.WriteLine("User has been created");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
I use UserPrinicipal here because when i use DirectoryEntry i can give the created user Admin rights but i havent found a way to set the PasswordNeverExpires option to true. With UserPrinicipal i can set the PasswordNeverExpires option to true, but i havent found a way to give it Admin rights.
If anyone knows how this is done, or know a way to do this better i would love to know how.
I want to know what is the correct way of doing this: lets say I have a login method that receives username and password, and log ins the user or return invalid username/password or not enough permissions. What is the correct way of doing this?
Way #1: throwing exception and handling in the user interface to display the error
public void Login(string username, string password)
{
if (SessionService.GetSession.IsLoggedIn)
{
throw new Exception("User is already logged in");
}
var user = GetByUsername(username);
if (user == null)
{
throw new LoginException(LoginResultEnum.InvalidUsername);
}
var hashPass = EncryptionService.Hash(password);
if (hashPass != user.password)
{
throw new LoginException(LoginResultEnum.InvalidPassword);
}
if (!user.HasPermission(PermissionTypeEnum.CanLogIn))
{
throw new MissingPermissionException(TipoPermisoEnum.CanLogIn);
}
SessionService.GetSession.Login(user);
}
Way #2: returning boolean true/false and handle the error in the UI (success or fail)
public bool Login(string username, string password)
{
if (SessionService.GetSession.IsLoggedIn)
{
return false;
}
var user = GetByUsername(username);
if (user == null)
{
return false;
}
var hashPass = EncryptionService.Hash(password);
if (hashPass != user.password)
{
return false;
}
if (!user.HasPermission(PermissionTypeEnum.CanLogIn))
{
return false;
}
SessionService.GetSession.Login(user);
return true;
}
Way #3: returning a LoginResult enum and handle in the UI
public LoginResult Login(string username, string password)
{
if (SessionService.GetSession.IsLoggedIn)
{
return LoginResult.AlreadyLoggedIn;
}
var user = GetByUsername(username);
if (user == null)
{
return LoginResult.InvalidUsername;
}
var hashPass = EncryptionService.Hash(password);
if (hashPass != user.password)
{
return LoginResult.InvalidPassword;
}
if (!user.HasPermission(PermissionTypeEnum.CanLogIn))
{
return LoginResult.Forbidden;
}
SessionService.GetSession.Login(user);
return LoginResult.OK;
}
In my view it better to create some dto if it is eligible for your case. So this dto will have the following properties:
public class LoginResponseDto
{
public bool Success { get; set; }
public string Error { get; set; }
}
And then you will return your response something like this:
public LoginResponseDto Login(string username, string password)
{
if (SessionService.GetSession.IsLoggedIn)
{
return new LoginResponseDto { Error = "User is already logged in" };
}
var user = GetByUsername(username);
if (user == null)
{
return new LoginResponseDto { Error = "There is no such user" };
}
var hashPass = EncryptionService.Hash(password);
if (hashPass != user.password)
{
return new LoginResponseDto { Error = "Incorrect password or username" };
}
if (!user.HasPermission(PermissionTypeEnum.CanLogIn))
{
return new LoginResponseDto { Error = "There is no permission to log in" };
}
SessionService.GetSession.Login(user);
return new LoginResponseDto { Success = true };
}
It is possible to see this tutorial "Create a secure ASP.NET MVC 5 web app with log in, email confirmation and password reset". Author of article use ViewBag in this article to send errors from controller and Succeeded to check whether login is okay.
In addition, try to avoid to show message about what is exactly wrong username or password.
I would say #3 is the best way.
#1 you are using Exception for non-exceptional circumstances. The control path is expected, so don't use Exceptions.
#2 By using a bool you are discarding information, is it InvalidPassword or Forbidden?
#3 Returns all information, allowing the UI to surface that information to the User.
I am using "BrowserSession" and added 2 variables to track the username and password, to login to a site.
private string _username;
private string _password;
public StoredAccountInfo RefreshAccountData(string username = _username, string password = _password)
{
if ((string.IsNullOrEmpty(username)) || (string.IsNullOrEmpty(password))
{
//throw Exception("Password Or Username Not Set");
}
BrowserLogin(username, password);//In case user is not logged in
StoredAccountInfo retdata = new StoredAccountInfo();
//populate retdata
return retdata;
I also added this function which sets the _username and _password variables
public void BrowserLogin(string username, string password)
{
if (Cookies == null)
{
//Do Site Login Here If not Logged In
Get(constants.BaseUrl);
FormElements["UserName"] = username;
FormElements["PassWord"] = password;
Post(constants.loginUrl);
_username = username;
_password = password;
}
}
However
public StoredAccountInfo RefreshAccountData(string username = _username, string password = _password)
gives me the syntax error
"default parameter value for 'username' must be a compile-time constant"
Anyone know a workaround or solution? I don't want to pass the username and password Every single time I call the RefreshAccountData method, however in case it gets called before the first browser login, I would like to be able to set the username and password variables from it.
I might just be completely missing a really simple way to do this as well. But I can't seem to think of any.
You could default to null and use those variables if null is passed:
public StoredAccountInfo RefreshAccountData(string username = null, string password = null)
{
username = username ?? _username;
password = password ?? _password;
if ((string.IsNullOrEmpty(username)) ||
(string.IsNullOrEmpty(password))
{
//throw Exception("Password Or Username Not Set");
}
Or you could provide a second method that doesn't take those arguments and pass the variables to your main method, this would let you catch when the caller actually tried to pass a username or password that happened to be null and throw an error.
public StoredAccountInfo RefreshAccountData()
{
RefreshAccountData(_username, _password);
}
Overloaded methods:
public void BrowserLogin(string username, string password)
{
...
}
public void BrowserLogin(string username)
{
BrowserLogin(username, _password);
}
public void BrowserLogin()
{
BrowserLogin(_username, _password);
}
Parameter object:
public class LoginParams
{
public string UserName { get; set; }
public string Password { get; set; }
}
public void BrowserLogin(LoginParams aParams)
{
if (aParams.UserName == null)
<use this._username>
if (aParams.Password == null)
<use this._password>
...
}
BrowserLogin(new LoginParams());
BrowserLogin(new LoginParams() { UserName = username });
BrowserLogin(new LoginParams() { UserName = username, Password = password });
You cannot use variables as optional parameters. You have to declare an overload of the method. So sad! :(
public StoredAccountInfo RefreshAccountData() {
return RefreshAccountData (_username, _password);
}
There is no way to use optional parameters for this unfortunately.
Let me explain why you cannot. Optional parameter values are put into the compiled code. So if you change the variable's value, the compiled code will not change, right? Long story short, compiled code cannot detect the variable's value has changed.
I'm trying to create my one custom Validation class, for logging users in and out. however.
When i log out, the Verafy Bool does not return false. (The cookie is not deleted)
What am i doing wrong? And is there anything i should be doing differently?
Hope you can help!
public static class Security
{
private static HttpCookie cookie = HttpContext.Current.Request.Cookies["Login"];
//Tells weather you are logged in or not
public static bool Verafy {
get
{
if (cookie != null)
return true;
else
return false;
}
}
//Removes cookie, (doesn't work!)
public static void signOut()
{
cookie = new HttpCookie("Login");
cookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.Cookies.Add(cookie);
}
//Creates a cookie for x days.
public static void SignIn(int Days)
{
cookie = new HttpCookie("Login");
cookie.Name = "Login";
cookie.Expires.AddDays(Days);
HttpContext.Current.Response.Cookies.Add(cookie);
}
//This is just temporarily..
public static bool VerafyUser(string Username, string Password)
{
if (Username == "123" && Password == "123")
{
return true;
}
else
{
return false;
}
}
}
You have static field for cookie here, so it will be shared between all users of your app, dude! If someone else logged in after you leave the app, cookie will be restored.
Read the article http://mikehadlow.blogspot.com/2008/03/forms-authentication-with-mvc-framework.html. Should help.
I think you have taken the wrong approach here by storing a static variable for your cookie. As you never set the reference to null your property will never return false.
Get rid of the static field and have your property actually check if the cookie exists e.g.
public bool LoggedIn
{
get { return HttpContext.Current.Request.Cookies["Login"] != null; }
}
I have this databases: table<User>(UserID,Name,Surname,Username,Password,Email), table<Role>(RoleID,RoleName,Description), and table<UsersInRole>(UserID,RoleID). I create a login authentication with username and password to access to the application (with Linq ToSql to store data), and it is right.
Now I wish to create a role for each user, but I don't know how work out it; I saw some features about it but it refers to web.app.
This is the code of the procedure that applies to login:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
public bool ValidateApplicationUser(string userName, string password)
{
{
var AuthContext = new DataClasses1DataContext();
var query = from c in AuthContext.Users
where (c.Username == userName.ToLower() && c.Password == password.ToLower())
select c;
if(query.Count() != 0 )
{
return true;
}
return false;
}
}
private void mahhh(object sender, RoutedEventArgs e)
{
bool authenticated = true;
{
if (usernameTextBox.Text !="" && passwordTextBox.Text != "")
{
authenticated = ValidateApplicationUser(usernameTextBox.Text , passwordTextBox.Text);
}
}
if (!authenticated)
{
MessageBox.Show("Invalid login. Try again.");
}
else
{
MessageBox.Show("Congradulations! You're a valid user!");
Window3 c = new Window3();
c.ShowDialog();
this.Close();
}
}
}
I don't know how to implement a method to assign a role to the user.
Do you have any idea or suggest to make it right?
First, try not to store passwords in the database; it is better to store a hash. I'm not quite sure what you mean "assign a role to the user" - are you having difficulty getting the role from the db? Or are you unsure what to do with it afterwards? If the latter, the "principal" is the way to go; at the simplest level:
string username = ...
string[] roles = ...
Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity(username), roles);
Now you can use role-based security, either declarative or imperative.
Declarative:
[PrincipalPermission(SecurityAction.Demand, Role="ADMIN")]
public void Foo()
{ // validated automatically by the .NET runtime ;-p
}
Imperative:
static bool IsInRole(string role)
{
IPrincipal principal = Thread.CurrentPrincipal;
return principal != null && principal.IsInRole(role);
}
...
bool isAdmin = IsInRole("ADMIN");