For the past few days, I was working in creating a login system for a webApp(asp.Net MVC 5) where I have a database already with username, credentials and Roles. I have found information from many blogs and stack overflow questions for my work and used it accordingly. Now before going online, I want to make sure that this login system is a secure one. I also want to know if there are some improvements which I can implement for this purpose.
For Authentication, I have implemeted as shown in the below article https://www.jamessturtevant.com/posts/ASPNET-Identity-Custom-Database-and-OWIN/. For Authorization, I have used Role Provider and implemented few required methods as like one shown below:
public class RoleList:RoleProvider
{
public override bool IsUserInRole(string username, string roleName)
{
if (username == null || username == "")
throw new ProviderException("User name cannot be empty or null.");
if (roleName == null || roleName == "")
throw new ProviderException("Role name cannot be empty or null.");
bool userIsInRole = false;
List<string> data = new List<string>();
String mycon = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
String myquery =
"SELECT " +
"r.RName, u.UName " +
"FROM " +
"Users u " +
"INNER JOIN " +
"UserRole ur " +
"ON " +
"u.Id=ur.UserId " +
"INNER JOIN " +
"Roles r " +
"ON " +
"ur.RoleId=r.Id " +
"WHERE " +
"u.UName=@UName " +
"AND " +
"r.Name=@RName";
var paramList = new List<SqlParameter>();
paramList.Add(new SqlParameter("@UName", username));
paramList.Add(new SqlParameter("@RName", roleName));
using (var reader = HelperClasses.DatabaseUtil.GetReader(myquery, mycon, paramList))
{
if (reader.HasRows)
{
userIsInRole = true;
}
}
return userIsInRole;
}
}
In Database In the database, I have 4 tables storing below information respectively.
- user(name and Id) and hash password(using Bcrypt).
- Roles.
- Users and Roles mapping.
- Salt with user id
In Login Controller
Login:
- Get salt and hash from database using inputed user name.
- Adding salt to the inputed plain text password.
- Validating the password by inputing hash and salted password to Bcrypt.
- If success, user will be authenticated by custom sign in manager as shown below
CustomSignInManager.SignIn(user, isPersistent: false, rememberBrowser: false);
Log Off:
public ActionResult LogOff()
{
HttpContext.GetOwinContext().Authentication.SignOut
(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index","Login");
}
To authorize an action
[Authorize(Roles = "Customer")]
public ActionResult Index()
{
return View();
}
As, it is an important segment in the application, I wish to know the pros and cons of it. I simplified the question as much as possible for easy understanding to readers. Is this the right way for a login system in asp.NET MVC 5? Can I do anything better?