Is there any way to get the full message response from the changepassword method? I need to find out why it's returning false. It never has in the past, the current password is correct and so is the emailresponse variable.
MembershipUser u = Membership.GetUser(emailresponse);
bool changed = u.ChangePassword("Password~123", txtPassword.Text);
if (changed){
//code emitted
}
Related
I am trying to verify a hashed password that is hashed in the register page, when I try to verify the hashed password with a entered password from the login, false is always returned.
I am hashing the password so:
string hashPassword = BCrypt.Net.BCrypt.HashPassword(Password);
The hashpassword is then saved to the database.
I try to verify the password so:
bool validPassword = BCrypt.Net.BCrypt.Verify(ProvidedPassword, StoredPassword);
Debug.WriteLine(validPassword);
if (validPassword)
{
Debug.WriteLine(ProvidedPassword + " is valid");
}
else
{
Debug.WriteLine("Passwords do not match");
}
I am using this source from github.
I have tried multiple methods and still always returns a false value.
I found the issue, my stored procedure parameters did not match my tables paremeters
I created a new Razor Pages app. I ran that app and created an account. (A confirmation email was sent, which I clicked.) And that account was working. But today, I'm unable to log in.
Invalid login attempt.
Even though I believe I remember the password, I tried the Forgot Password feature. No email was sent.
I've reviewed my account in the database. Here are the values of the relevant columns from the AspNetUsers table:
EmailConfirmed: True
LockoutEnd: NULL
AccessFailedCount: 0
Next, I tried to scaffold the Login and Forgot Password so I could debug the code. But this failed. (You can see my post about this issue on GitHub.)
So at this point, I'm blocked. Can anyone else suggest other things I might try to resolve this issue? What other things can cause this behavior?
SignInManager.PasswordSignInAsync requires Username and Password, not an Email and Password so if you have Username same as Email it will work with you else it won't work.so makesure make UserName value = Email.
Also, It's better to query the user by awaiting _userManager.FindByEmailAsync(Input.Email) Then pass this user to the PasswordSignInAsync make sure FindByEmailAsyncto check if the user with the given name exists something Like this:-
var user = await _userManager.FindByEmailAsync(Input.Email);
var result = await _signInManager.PasswordSignInAsync(user, Input.Password, Input.RememberMe, lockoutOnFailure: false);
I think it will help to resolve your issue.
now you check are you set UserName value = Email. or no
beacuse in asp.net core identity by default use user name for login
I have faced a similar kind of situation, in my case security stamp value of the user recored in db table had get deleted somehow.
Also check whether username column has the sama value as Email column, if you use email as the username.
If you use scaffolded identity by default username column repeats the email value.
Please try to log in from a different machine with a different internet connection - this is an issue I had too - I solved it by using a different computer with the same password & username
"Invalid login attempt" typically means either username or password is incorrect. Most likely password.
I found I cannot receive any email so resetting password by email is a not an option in the default scaffolded project.
Here is a way to reset the password: Register a new user(remember the password:-) ), go to the database and copy the passwordhash from new user and apply it to the user you have problem with and see if it logs with the new password in now.
Updates
The real reason of "Invalid login attempt" isn't revealed to the user but it is logged. So if you run the application in debug mode, it will capture the reason. E.g. if I type in wrong password, I will get following in the output console:
warn: Microsoft.AspNetCore.Identity.UserManager[0]
Invalid password for user.
warn: Microsoft.AspNetCore.Identity.SignInManager[2]
User failed to provide the correct password.
Update : login flow when you get "Invalid login attempt"(Razor page)
https://github.com/aspnet/Identity/blob/master/src/UI/Areas/Identity/Pages/V4/Account/Login.cshtml.cs
You get "Invalid login attemp" because _signInManager.PasswordSignInAsync method return SignResult.Failed or SignInResult.NotAllowed
public override async Task<IActionResult> OnPostAsync(string returnUrl = null){
....
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
}
https://github.com/aspnet/Identity/blob/master/src/Identity/SignInManager.cs
You get SignInResult.Failed with no logging if user cannot be found
public virtual async Task<SignInResult> PasswordSignInAsync(string userName, string password,
bool isPersistent, bool lockoutOnFailure)
{
var user = await UserManager.FindByNameAsync(userName);
if (user == null)
{
return SignInResult.Failed;
}
return await PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure);
}
This method calls bellow method which only returns error, SignInResult.Success or put out a log message:
public virtual async Task<SignInResult> CheckPasswordSignInAsync(TUser user, string password, bool lockoutOnFailure)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var error = await PreSignInCheck(user);
if (error != null)
{
return error;
}
if (await UserManager.CheckPasswordAsync(user, password))
{
var alwaysLockout = AppContext.TryGetSwitch("Microsoft.AspNetCore.Identity.CheckPasswordSignInAlwaysResetLockoutOnSuccess", out var enabled) && enabled;
// Only reset the lockout when TFA is not enabled when not in quirks mode
if (alwaysLockout || !await IsTfaEnabled(user))
{
await ResetLockout(user);
}
return SignInResult.Success;
}
Logger.LogWarning(2, "User {userId} failed to provide the correct password.", await UserManager.GetUserIdAsync(user));
PresigninCheck and CanSignUser deals with confirmation and lock and you will get a different message in UI other than "Invalid login attempt", and also has some logs:
protected virtual async Task<SignInResult> PreSignInCheck(TUser user)
{
if (!await CanSignInAsync(user))
{
return SignInResult.NotAllowed;
}
if (await IsLockedOut(user))
{
return await LockedOut(user);
}
return null;
}
CanSignInAsync can return fasle which cause SignInResult.NotAllowed, but all with logging:
public virtual async Task<bool> CanSignInAsync(TUser user)
{
if (Options.SignIn.RequireConfirmedEmail && !(await UserManager.IsEmailConfirmedAsync(user)))
{
Logger.LogWarning(0, "User {userId} cannot sign in without a confirmed email.", await UserManager.GetUserIdAsync(user));
return false;
}
if (Options.SignIn.RequireConfirmedPhoneNumber && !(await UserManager.IsPhoneNumberConfirmedAsync(user)))
{
Logger.LogWarning(1, "User {userId} cannot sign in without a confirmed phone number.", await UserManager.GetUserIdAsync(user));
return false;
}
return true;
}
I have an existing ASP.NET Core MVC application that I want to add a new API method in a controller. I want to touch the authentication/authorization code as little as possible, so I don't want to write a new authentication middleware for this one API.
The method is supposed to return some type of data if the user is anonoymous/unknown. And it should return more specific and potentially personal information if the user is signed in and has a valid user.
Is it safe to skip the [Authorize] attribute, and check only check the HttpContext.User (https://learn.microsoft.com/en-us/dotnet/api/system.web.httpcontext.user?view=netframework-4.8) property for the username?
Can I assume that the signature has been verified by the OpenID Connect middleware?
// No Authorize attribute
public IActionResult MyApi()
{
string userName = System.Security.Claims.Claim idClaim = this.HttpContext.User?.Claims?.FirstOrDefault(a => a.Type == "sub")?.Value;
// Can I assume that the User object only is non-null if the OAuth signature is actually verified?
// Or is fake-cookies possible?
}
Authorization does not do anything in regards to authentification, it's only a mechanism to check whether the authenticated user has access to the requested resource. It's like a layer on top of authentication.
The presence of HttpContext.User does not necessarily indicate an authenticated user, but HttpContext.User.Identity.IsAuthenticated does. For ClaimsIdentity it basically just checks whether the field AuthenticationType is not empty.
Therefore, it's safe to assume the user is authenticated if it has AuthenticationType field set. It's also safe to assume that if the field Name is not empty as unauthenticated users can't have it set.
I use a custom extensions method to read the username from the current identity:
public static bool TryGetUserName(this IIdentity identity, out string username)
{
try
{
username = Microsoft.AspNet.Identity.IdentityExtensions.GetUserName(identity);
return true;
}
catch (ArgumentNullException ane)
{
username = null;
return false;
}
}
And I use this extension in my API method by calling:
bool isAuth = this.User?.Identity?.TryGetUserName(out username) ?? false;
I have the following C# method which is used for a custom authentication implementation:
public bool Authenticate(AuthenticateRequest userCredentials)
{
var encoding = Encoding.GetEncoding("iso-8859-1");
var userName = encoding.GetString(Convert.FromBase64String(userCredentials.NetworkUserId));
var password = encoding.GetString(Convert.FromBase64String(userCredentials.Password));
var pc = new PrincipalContext(ContextType.Domain, userCredentials.DomainName);
var isValid = pc.ValidateCredentials(userName, password);
return isValid;
}
This works well when the correct user credentials are provided. This also works well when incorrect user credentials are provided. The problem is that when invalid user credentials are provided only 1 time, the user account gets locked out and subsequent login attempts fail, even when the proper credentials are submitted. Is there a way to configure this code or the server to allow 3 login attempts before the user account lockout happens?
I'm working with the Active Directory DirectoryServices.AccountManagement API, and am attempting to connect to the server using the following code:
PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, (server + ":" + port), loginUsername, loginPassword);
The first thing I would like to do is check that the loginUsername and loginPassword are valid and have enough permissions in the Active Directory instance. To achieve this, I call the following:
bool x = principalContext.ValidateCredentials(null, null);
According to the documentation, this validates the credentials specified in the constructor since null is passed. In the debugger, the following errors are thrown, indicating that the credentials are false:
However, the actual result to the ValidateCredentials check is strangely enough returning true and the code thus continues to execute.
How can this be solved?
EDIT:
Here is another screenshot elaborating on the errors. As shown in the screenshot, I am calling the ValidateCredentials method, and passing null values for the username and password, which according to the documentation will attempt to validate the credentials passed in the PrincipalContext class' constructor.
The screenshot also shows how the username and passwords passed are both "test", which are invalid and do not exist in the Active Directory. The method is returning true, even though there are a number of errors displayed.
You simply need to stop looking up null values...
if (string.IsNullOrEmpty(password) || string.IsNullOrEmpty(username)) return false;
I ran some tests
using (var pc = new PrincipalContext(ContextType.Domain, "mydomain.lan")){
var isOk1 = pc.ValidateCredentials(null,null); //Always true
var isOk2 = pc.ValidateCredentials("notexists","wrong"); //false
var isOk2 = pc.ValidateCredentials("existing","correct"); //true
}
and
using (var pc = new PrincipalContext(ContextType.Domain, "mydomain.lan", "notright","wrong")){
var isOk1 = pc.ValidateCredentials(null,null); //Always true
var isOk2 = pc.ValidateCredentials("notexists","wrong"); //false
var isOk2 = pc.ValidateCredentials("existing","correct"); //true
}
So the ValidateCredentials does not really need a user in the context... If you provide a false one a following lookup for say, users groups, will fail however
Yes, documentation reads:
The ValidateCredentials method binds to the server specified in the constructor. If the username and password parameters are null, the credentials specified in the constructor are validated. If no credential were specified in the constructor, and the username and password parameters are null, this method validates the default credentials for the current principal.
(http://msdn.microsoft.com/en-us/library/bb154889%28v=vs.100%29.aspx)
But I can't verify, that the creds in the constructor is in play
EDIT: You have already accepted, but maybe you can use this method for your problem?
using (var pc = new PrincipalContext(ContextType.Domain, "domain.lan", username, password))
{
if (pc.ValidateCredentials(username, password))
{
try
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(pc)))
{
searcher.QueryFilter.SamAccountName = username;
Principal u = searcher.FindOne();
}
}
catch (Exception)
{
return "no rights to work on ad";
}
}
else
{
return "user cannot login";
}
}