Bcrypt password verifying - c#

I'm trying to decrypt the password on the login method, but it allows to login with any password I type in, not sure why, maybe someone could help me out?
My login method in the db layer:
public string loginUser(string userName, string pass)
{
string result = "";
try
{
var mongoClient = new MongoClient("mongodb://localhost");
var database = mongoClient.GetDatabase("SearchForKnowledge");
var coll = database.GetCollection<BsonDocument>("Users");
var filter = Builders<BsonDocument>.Filter.Eq("userName", userName);
var results = coll.Find(filter).ToList().First();
if (BCrypt.Net.BCrypt.Verify(pass, results["password"].ToString()))
{
result = results["userName"].ToString();
}
}
catch (Exception ex)
{
result = "";
}
return result;
}
My user controller:
public ActionResult Login(UsersLogin form)
{
User user = new User();
UserDB udb = new UserDB();
if (!form.Username.IsEmpty())
{
udb.loginUser(form.Username, form.Password);
Session["userName"] = form.Username;
return RedirectToRoute("Home");
}
return RedirectToRoute("Login");
}

The problem is in your controller
udb.loginUser(form.Username, form.Password);
Session["userName"] = form.Username;
return RedirectToRoute("Home");
You call udb.loginUser(form.Username, form.Password);, but you never check the return value of udb.loginUser method, so your code will always redirect to the home page no matter what the user name and password are.
Based on the code of loginUser method, it will return an empty string if the login fails, so change the above three lines of code to below
var loginResult = udb.loginUser(form.Username, form.Password);
if (!string.IsNullOrEmpty(loginResult))
{
Session["userName"] = form.Username;
return RedirectToRoute("Home");
}

Related

ModelState.AddModelError is setup to display Canned message instead of real Error

In my website i had a group of people working on my site and i have this code that they put a canned message in for an error. When i debug the code it is actually a different error but displays this canned message. For instance when i put the information in the form i used an email address that already exists in the database but it is showing a message to check the password requirements. How can this be fixed to show the actual error. To me it also seems like there is a lot code going on in this that may not need to be or can be achieved cleaner Your thoughts?
Code of Post Action:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateCompanyUser(ExpandedUserDTO ExpandedUserDTO)
{
try
{
if (ExpandedUserDTO == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var Email = ExpandedUserDTO.Email.Trim();
var UserName = ExpandedUserDTO.UserName.Trim();
var Password = ExpandedUserDTO.Password.Trim();
if (UserName == "")
{
throw new Exception("No Username");
}
if (Password == "")
{
throw new Exception("No Password");
}
// UserName is LowerCase of the Email
// UserName = Email.ToLower();
// Create user
var objNewAdminUser = new Models.ApplicationUser { UserName = UserName, Email = Email };
var AdminUserCreateResult = UserManager.Create(objNewAdminUser, Password);
if (AdminUserCreateResult.Succeeded == true)
{
string strNewRole = Convert.ToString(Request.Form["Roles"]);
if (strNewRole != "0")
{
// Put user in role
UserManager.AddToRole(objNewAdminUser.Id, strNewRole);
}
var viewModel = new Users();
{
viewModel.UsersId = Convert.ToString(Guid.NewGuid());
viewModel.Email = Email;
viewModel.FirstName = UserName;
viewModel.AspNetUsersId = objNewAdminUser.Id;
viewModel.CreatedDate = System.DateTime.Now;
viewModel.UpdatedDate = System.DateTime.Now;
};
UsersBusinessModels Login = new UsersBusinessModels();
var results = Login.insertUserWithougAsny(viewModel);
string[] roleRemove = new string[2] { "Administrator", "CompanyAdmin" };
ViewBag.Roles = GetAllRolesAsSelectList().Where(k => !roleRemove.Contains(k.Text)).ToList();
// return RedirectToAction();
Response.Redirect("/Customer/ManageUsers/" + User.Identity.GetUserId());
return PartialView();
}
else
{
ViewBag.Roles = GetAllRolesAsSelectList();
ModelState.AddModelError(string.Empty,
"Error: Failed to create the user. Check password requirements.");
return PartialView(ExpandedUserDTO);
}
}
catch (Exception ex)
{
ViewBag.Roles = GetAllRolesAsSelectList();
ModelState.AddModelError(string.Empty, "Error: " + ex);
string[] roleRemove = new string[2] { "Administrator", "CompanyAdmin" };
ViewBag.Roles = GetAllRolesAsSelectList().Where(k => !roleRemove.Contains(k.Text)).ToList();
return PartialView(ExpandedUserDTO);
}
}

Getting password from mongodb c#

I am trying to create a login method and I need to get a password from the corresponding user. This is my database layer code:
public int loginUser(string userName, string pass)
{
int result = 0;
var credentials = MongoCredential.CreateMongoCRCredential("SearchForKnowledge", userName, pass);
var settings = new MongoClientSettings
{
Credentials = new[] { credentials }
};
try
{
var mongoClient = new MongoClient(settings);
var database = mongoClient.GetDatabase("SearchForKnowledge");
var coll = database.GetCollection<BsonDocument>("Users");
var filter = Builders<BsonDocument>.Filter.Eq("userName", userName);
var query = coll.Find(filter);
//??????????
}
catch (Exception ex) {
result = 0;
}
return result;
}
as you can see if the login is success im trying to return 1 and if it fails, 0 (for redirecting purposes). I am struggling to check if the username matches password set to it. At the moment I just made a filter, passed it to the method Find and im dead stuck at this point. How do I return that user's password from mongodb and compare it to the one passed as a parameter?
Try something like this:
public int loginUser(string userName, string pass)
{
int result = 0;
//Here you use credentials for the connection, not the one passed
//to the method:
var credentials = MongoCredential.CreateMongoCRCredential("SearchForKnowledge", connectionUsername, connectionPass);
var settings = new MongoClientSettings
{
Credentials = new[] { credentials }
};
try
{
var mongoClient = new MongoClient(settings);
var database = mongoClient.GetDatabase("SearchForKnowledge");
var coll = database.GetCollection<BsonDocument>("Users");
var filter = Builders<BsonDocument>.Filter.Eq("userName", userName);
var result = await coll.Find(filter).ToListAsync().First();
if(result["Password"] == pass)
{
result = 1;
}
}
catch (Exception ex) {
result = 0;
}
return result;

registration confirmation email

[HttpPost]
public ActionResult Register(User user)
{
if (ModelState.IsValid)
{
UserAPIController uApi = new UserAPIController(true);
HttpResponseMessage response = uApi.Register(user, Request.QueryString["TeamId"]);
if (response.StatusCode == System.Net.HttpStatusCode.Conflict)
{
ModelState.AddModelError("", HttpContext.GetGlobalResourceObject("LanguageResource", "DuplicateEmailErrorMessage").ToString());
return View();
}
//Send Registration Email
string EmailBodyStr = string.Empty;
string EmailFrom = Helpers.CommonFunctions.GetApplicationSettingValue("SystemEmailId");
string EmailSub = HttpContext.GetGlobalResourceObject("LanguageResource", "EmailTemplate_Reistration_Subject").ToString();
string userName = user.FullName;
if (string.IsNullOrEmpty(userName))
{
userName = user.Email;
}
EmailBodyStr = HttpContext.GetGlobalResourceObject("LanguageResource", "EmailTemplate_Registration_TeamLeader_Body").ToString();
EmailBodyStr = EmailBodyStr.Replace("[UserFullName]", userName);
string email = HttpUtility.UrlEncode(Helpers.Encrypt.EncryptString(user.Email));
EmailBodyStr = EmailBodyStr.Replace("[NavigationLink]", "click here");
if (EmailFrom != string.Empty)
{
Helpers.Emailer.SendEmail(user.Email, EmailSub, EmailBodyStr, EmailFrom);
}
ModelState.AddModelError("", HttpContext.GetGlobalResourceObject("LanguageResource", "SuccessfullRegistrationMessage").ToString());
}
return View(user);
}
I have created a registration form in mvc4 in which the user get confirmation email once it get registered but its sending the same registration email two times. Above is the code which is used for registration confirmation.
Please let me know where is the problem in code and why its triggering same event two times.

Forget password form in asp.net mvc 4

I try to implement forget password form in my asp.net mvc 4 project, everything works fine, but when I try to login to system with new password it told me that I have wrong password.
[HttpPost]
public ActionResult ForgetPassword(UserViewModel userModel) {
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var result = new string(
Enumerable.Repeat(chars, 8)
.Select(s => s[random.Next(s.Length)])
.ToArray());
User user = _userRepo.GetUserByEmail(userModel.Email);
if (user == null) {
ViewBag.Error = Resources.Account.userEmailNotExist;
return View(userModel);
}
String newHashedPassword = Crypto.HashPassword(result);
user.Password = newHashedPassword;
user.LastPasswordChangedDate = DateTime.UtcNow;
_userRepo.SaveChanges();
string enMessage = "Your new password: " + result;
var httpCookie = Request.Cookies["lang"];
if (httpCookie != null && httpCookie.Value == "en") {
_mailHelper.SendEmail(userModel.Email, "New password", enMessage);
}
return RedirectToAction("ConfirmPasswordChange", "Account");
}
Login form:
[HttpPost]
public ActionResult Login(UserViewModel user) {
var users = _userRepo.GetAllEntitiesWithParam("JobsDb_Users_GetByEmail", user.Email).FirstOrDefault();
...
try {
var tryLogin = WebSecurity.Login(users.Username, user.Password, true);
if (tryLogin == WebSecurity.MembershipLoginStatus.Failure)
{
var httpCookie = Request.Cookies["lang"];
if (httpCookie != null && httpCookie.Value == "en") {
ViewBag.Error = "Your password is incorrect.";
new SeoHelper().ReturnSeoTags(this, "Login");
}
return View(user);
}
...
} catch {
...
}
}
inside WebSecurity
public static MembershipLoginStatus Login(string username, string password, bool rememberMe) {
if (Membership.ValidateUser(username, password)) {
FormsAuthentication.SetAuthCookie(username, rememberMe);
return MembershipLoginStatus.Success;
} else {
return MembershipLoginStatus.Failure;
}
}
inside Membership
public override bool ValidateUser(string username, string password) {
if (string.IsNullOrEmpty(username)) {
return false;
}
if (string.IsNullOrEmpty(password)) {
return false;
}
User user = _userRepository.GetAll().FirstOrDefault(usr => usr.Username == username);
if (user == null) {
return false;
}
if (!user.IsApproved.Value) {
return false;
}
if (user.IsLockedOut.Value) {
return false;
}
String hashedPassword = user.Password;
Boolean verificationSucceeded = (hashedPassword != null && Crypto.VerifyHashedPassword(hashedPassword, password));
if (verificationSucceeded) { //here is I have false if try to login using password from forget form
user.PasswordFailuresSinceLastSuccess = 0;
user.LastLoginDate = DateTime.UtcNow;
user.LastActivityDate = DateTime.UtcNow;
} else {
int failures = user.PasswordFailuresSinceLastSuccess.Value;
if (failures < MaxInvalidPasswordAttempts) {
user.PasswordFailuresSinceLastSuccess += 1;
user.LastPasswordFailureDate = DateTime.UtcNow;
} else if (failures >= MaxInvalidPasswordAttempts) {
user.LastPasswordFailureDate = DateTime.UtcNow;
user.LastLockoutDate = DateTime.UtcNow;
user.IsLockedOut = true;
}
}
_userRepository.SaveChanges();
if (verificationSucceeded) {
return true;
}
return false;
}
First step is to open up your database and verify that the new password was actually persisted. If it has, the most likely cause is that your repository is working with stale (cached) data.
If you're using Entity Framework, this happens because the framework will, by default, cache the state of the database at the time the DbContext is created, so it is retaining your original password. You can verify this by logging in with the original password.
I am not sure but following code does not look right to me:
User user = _userRepo.GetUserByEmail(userModel.Email);
if (user == null) {
ViewBag.Error = Resources.Account.userEmailNotExist;
return View(userModel);
}
String newHashedPassword = Crypto.HashPassword(result);
user.Password = newHashedPassword;
user.LastPasswordChangedDate = DateTime.UtcNow;
_userRepo.SaveChanges();
You fetched the user from repository, make changes to user object in memory and then called SaveChanges() on the repository. Does that work in your world? How does _userRepo.SaveChanges(); knows which object has changed. Do you see correct hashed value in DB after the call? What value you see in ValidateUser() method for password? Is the hashing algorithm consistent both while generating hashed password and while verifying?
I could be wrong, if that's the case it will be good if you share little bit more of analysis around the question I asked above.

Validation password with Active Directory

I'd like check the the login and the password match with the AD info. I tried with this piece of coode but I get an exception on FindOne (bad username or password .. but they are correct). I know there is the PrincipalContext solution but I need to be able to set the server (Production, Dev, ...)
Thanks,
var Ad = new DirectoryEntry("LDAP://server1.domain.com", username, password);
var AdSearcher = new DirectorySearcher(Ad);
AdSearcher.Filter = String.Format("(anr={0})", username);
AdSearcher.PropertiesToLoad.Add("sAMAccountName");
AdSearcher.PropertiesToLoad.Add("displayName");
var AdSearcherResults = AdSearcher.FindOne();
var userFullName = AdSearcherResults.Properties["displayName"][0].ToString();
var userUid = AdSearcherResults.Properties["sAMAccountName"][0].ToString();
if (Membership.ValidateUser(username, userUid))
return true;
return false;
Update1 I tried this too :
using (var context = new PrincipalContext(ContextType.Domain, "server1.domain.com"))
{
var isValid = context.ValidateCredentials(username, password);
}
My computer is not connected on the domain but should be work I think.
My code for ActiveDirectory Auth.
public DirectoryEntry connDirectory(string usr, string pwd)
{
string ip = iniMan.IniRead("LDAP", "adres");
DirectoryEntry oDE;
oDE = new DirectoryEntry(ip, usr, pwd, AuthenticationTypes.Secure);
return oDE;
}
public bool AD_Login(string kullanici_adi, string sifre)
{
try
{
DirectoryEntry entLogin = connDirectory(kullanici_adi, sifre);
object loginObj = entLogin.NativeObject;
return true;
}
catch (Exception ex)
{
return false;
}
}
void TestMetod(){
if(AD_Login("ozan","ozan"){
//ok
}
}

Categories

Resources