WebSecurity.ChangePassword returning FALSE value - asp.net

I can't figure out why my WebSecurity.ChangePassword is not working. Here's the piece of code I'm working on.
if (WebSecurity.ChangePassword(USER, oldpass, password)) {
Response.Redirect("~/SuperAdmin");
return;
}else {
ModelState.AddFormError(USER);
// I put the each WebSecurity.ChangePassword parameter to this parameter to check whether
//each parameter valid or not (print it out)
}
and for each parameter of WebSecurity.ChangePassword, I retrieve it from the database as follows
if(IsPost){
Validation.RequireField("email", "Masukkan email");
Validation.RequireField("password", "Masukkan Password");
Validation.RequireField("userid", "user ID tidak ada!");
email = Request.Form["email"];
password = Request.Form["password"];
userId = Request.Form["userId"];
if(Validation.IsValid()){
var db = Database.Open("StarterSite");
var updateCommand2 = "UPDATE UserProfile SET Email=#0 WHERE UserId=#1";
db.Execute(updateCommand2, email,userId);
var USER = db.QueryValue("SELECT a.Email FROM UserProfile a, webpages_Membership b WHERE a.UserId=b.UserId AND a.UserId= #0", userId);
var oldpass = db.QueryValue("SELECT Password FROM webpages_Membership WHERE UserId = #0", userId);
Can anyone tell me what seems to be the problem here? Thanks in advance

The WebPages Membership has everything built you do not need to get the users email address and password (I am guessing the email address is the username right?) The ChangePassword method takes 3 arguments. which is UserName, CurrentPassword, NewPassword.
The reason your getting false is because your getting the old password from the database based on the users current Id, but the old password does not match the users current password because old one is encrypted and you're not encrypting the one they submit (in fact you don't even have a field for them to enter their current password).
The WebPages Membership provider will do all the updating you do not need open the database and update the users password, the weird thing you're doing is telling the user to enter a new password but not asking for the current one! Here see this for more information:
http://www.thecodingguys.net/reference/asp/websecurity-changepassword

Make sure the user you are trying to change password for is not LockedOut. You can check it by this
select * from aspnet_membership
where
IsLockedOut = 1

Related

Whether the password stores in the keystone's password table, and if is, how does the password maps the user's password?

Where is the user's password is store ?
I can not find in the keystone's user table:
But I can find in the keystone's password table:
does the password is map the user's password?
My question is :
Whether the password stores in the keystone's password table? and if is, how does the password maps the user's password?
and does the password's encrypted? I never see this type password.
I never see this type password. because I use the openstacksdk register a project and user, I can not login. I don't know why. So, I want to get some idea about it here.
My project's django code is bellow, use openstacksdk to register:
def register(request):
if request.method == 'GET':
return render(request, 'frontend/register.html')
elif request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
phone = request.POST.get('phone')
email = request.POST.get('email')
usertype = 1
app_user_params = {
"username":username,
"password":hashlib.sha1(password).hexdigest(), # sha1加密
"phone":phone,
"email":email,
"usertype":usertype
}
user_form = UserMF(app_user_params)
if user_form.is_valid():
obj_user = models.User.objects.filter(username=username)
obj_phone = models.User.objects.filter(phone=phone)
obj_email = models.User.objects.filter(email=email)
# 使用admin用户创建project和user
from openstack import connection
connection = connection.Connection(**settings.ADMIN_OPENRC)
admin_conn = OpenstackConn.OpenstackAdminConn()
admin_conn.admin_conn = connection
# 创建项目(先创建项目,再创建用户)
project_params = {
"description":username+"'s project",
"is_domain":False,
"enable":False, # I set True still has this issue.
"name":username, # 给的是用户名,也是唯一的
}
try:
new_project = admin_conn.admin_conn.identity.create_project(**project_params) # create_project
print (new_project, new_project.id, "new project created")
except Exception as e:
print (e.message)
return HttpResponse(json.dumps({'status_code':0,'info':e.message.encode('utf-8')}))
# 创建 openstack_cloud user
user_params = {
"default_project_id":new_project.id,
"email":email,
"enabled":False,
"name":username,
"password":password
}
try:
new_user = admin_conn.admin_conn.identity.create_user(**user_params)
print (new_user, new_user.id, "new user created")
except Exception as e:
admin_conn.admin_conn.identity.delete_project(new_project)
print (e.message)
return HttpResponse(json.dumps({'status_code': 0, 'info': e.message.encode('utf-8')}))
I don't know whether I write wrong, or password will encrypt.
EDIT-1
I print the new created user, and user.id:
(openstack.identity.v3.user.User(name=liaodalin15, links={u'self': u'http://controller:5000/v3/users/66c60156d0f24a118df54f19e2705aaf'}, enabled=False, domain_id=default, email=xxxxxxxxx#126.com, default_project_id=a829eda8c4de479d8ca5c3a4335c793a, password=liaodalin15, id=66c60156d0f24a118df54f19e2705aaf, password_expires_at=None), u'66c60156d0f24a118df54f19e2705aaf')
Seems the password did now encrypt. Does this should encrypt by ourself?
In the end, I figured out the issue:
Because use openstacksdk create user default is disabled, so I should eable it.

How to check password manually in Asp.Net identity 2?

This might actually be more of a conceptual question. In Asp.Net Identity the PasswordHasher generates a different hash for the same string every time you do:
new PasswordHasher.HashPassword("myString");
Now if for some reason I need to manually compare a user's input to the password saved in the database, I will most probably get a different string when I hash the user's entered password, than the one that is stored in the database.
Can someone please explain this to me? Shouldn't hashing the same string result in the same hash and if not, how does Identity itself realize that two different hashes are in fact the same?
PasswordHasher generates different hashes each time because it uses salting technique. This technique secure the hashed password against dictionary attacks. By the way you could use following code to manually verify the password:
if(PasswordHasher.VerifyHashedPassword("hashedPassword", "password")
!= PasswordVerificationResult.Failed)
{
// password is correct
}
var user = _userManager.Users.SingleOrDefault(p => p.PhoneNumber == model.PhoneNumber);
if (user == null)
{
return RedirectToAction(nameof(Login));
}
var result1 = _userManager.PasswordHasher.VerifyHashedPassword(user, user.PasswordHash, model.Password);
if (result1 != PasswordVerificationResult.Success)
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}

ASP Identity - AddToRoleAsync

I have a problem using the Microsoft AddToRoleAsync() function.
For usernames where there is a hyphen in them I cannot get it to work successfully. For example:
var user = new ApplicationUser();
var email = "name-surname#company.com";
user = await userManager.FindByEmailAsync(email);
await userManager.AddToRoleAsync(user.Id, "Admin");
I don't get an error thrown, the user just doesn't get added to the role and an entry never appears in the AspNetUserRoles.
However, as soon as I remove the hyphen in the email / username the AddToRoleAsync() works perfectly, which seems strange as this function takes an Id and role name.
We have the same value for both the email and username field.
Can anyone help ?

How to authencticate the encrypt password with input password value?

Here we call webapi service from mobile application to authenticate the userid and encrypted password in database.
So to authenticate I encrypt the input password and compare with database password?
Another question: Is it correct what I am doing?
Or is it a better way to decrypt the database password value and check with input value. If second way is better, how can I do that?
Below is my code:
using (LoginServiceEntities context = new LoginServiceEntities())
{
var crypto = new SimpleCrypto.PBKDF2();
var encrypass = crypto.Compute(Password);
var user = (from u in context.user_master
where String.Compare(u.UserID, UserID, StringComparison.OrdinalIgnoreCase) == 0
&& u.Password== encrypass
select u).FirstOrDefault();
return user != null;
}
Password in database should not be decrypted.
What you are doing is correct. Just compare the encrypted password in database with the encrypted input

Storing DotNetOpenAuth information and user info retrieval

This question is a bit of a structural/design question as I'm having trouble working out the best way to perform the task.
In my MVC app, I am using DotNetOpenAuth (3.4) as my login information provider and just using the standard FormsAuthentication for cookies etc.
The current user table in the DB has:
UserId (PK, uniqueidentifier)
OpenIdIdentifier (nvarchar(255))
OpenIdDisplay (nvarchar(255))
Displayname (nvarchar(50))
Email (nvarchar(50))
PhoneNumber (nvarchar(50))
As the UserId is the clear identifier for a user (they should be able to change their OpenId provider at a later date), it is the key that other tables link to (for a user).
This is the current code, that on a successfull authentication, creates a temporary user and redirects to Create Action.
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false);
var users = new UserRepository();
if (!users.IsOpenIdAssociated(response.ClaimedIdentifier))
{
var newUser = new DueDate.Models.User();
newUser.OpenIdIdentifer = response.ClaimedIdentifier;
newUser.OpenIdDisplay = response.FriendlyIdentifierForDisplay;
TempData["newUser"] = newUser;
return this.RedirectToAction("Create");
}
And now for the crux of the question:
Is the response.ClaimedIdentifier the correct piece of information to be storing against a user?
Is FormAuthentication.SetAuthCookie the preferred way to forms authentication? Or is there a better way?
When I call SetAuthCookie, there is no data relating to the user except for the ClaimedIdentifier. If I'm consistently referring to their UserId, is a better idea to create the user, then store that UserId in the cookie instead of the ClaimedIdentifier?
If I'm using that UserId in a number of places, how do I either retrieve it from the cookie, or store it somewhere else more logical/useful?
A bit long winded but I've been having trouble trying to work out the best way to do this/
1.Is the response.ClaimedIdentifier the correct piece of information to be storing against a user?
Yes. And make sure the column you store it in the database with is case sensitive. Here is a table schema that demonstrates how to make sure it is case sensitive. This comes out of the DotNetOpenAuth project template's database schema. The "CS" bit of the specified collation stand for Case Sensitive.
CREATE TABLE [dbo].[AuthenticationToken] (
[AuthenticationTokenId] INT IDENTITY (1, 1) NOT NULL,
[UserId] INT NOT NULL,
[OpenIdClaimedIdentifier] NVARCHAR (250) COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
[OpenIdFriendlyIdentifier] NVARCHAR (250) NULL,
[CreatedOn] DATETIME NOT NULL,
[LastUsed] DATETIME NOT NULL,
[UsageCount] INT NOT NULL
);
2.Is FormAuthentication.SetAuthCookie the preferred way to forms authentication? Or is there a better way?
For MVC apps it definitely is, since you still can return your preferred ActionResult from the method.
3.When I call SetAuthCookie, there is no data relating to the user except for the ClaimedIdentifier. If I'm consistently referring to their UserId, is a better idea to create the user, then store that UserId in the cookie instead of the ClaimedIdentifier?
That sounds like personal preference. But I would typically go with user_id, since it might result in a faster database lookup every time an HTTP request comes in that requires you to look up any user information.
4.If I'm using that UserId in a number of places, how do I either retrieve it from the cookie, or store it somewhere else more logical/useful?
FormsAuthentication does provide a way to store more information in its encrypted cookie than just username, but it is harder than you'd expect to use it. This snippet comes out of DotNetOpenAuth's web SSO RP sample:
const int TimeoutInMinutes = 100; // TODO: look up the right value from the web.config file
var ticket = new FormsAuthenticationTicket(
2, // magic number used by FormsAuth
response.ClaimedIdentifier, // username
DateTime.Now,
DateTime.Now.AddMinutes(TimeoutInMinutes),
false, // "remember me"
"your extra data goes here");
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));
Response.SetCookie(cookie);
Response.Redirect(Request.QueryString["ReturnUrl"] ?? FormsAuthentication.DefaultUrl);
Then you can get at that extra data in a future HTTP request with this:
var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie != null) {
var ticket = FormsAuthentication.Decrypt(cookie.Value);
if (!string.IsNullOrEmpty(ticket.UserData)) {
// do something cool with the extra data here
}
}

Resources