/// <summary> /// Verifies a user's hashed password /// </summary> /// <param name="user"></param> /// <param name="hashedPassword"></param> /// <param name="providedPassword"></param> /// <returns></returns> /// <exception cref="InvalidOperationException">Thrown when the correct hashing algorith cannot be determined</exception> public override PasswordVerificationResult VerifyHashedPassword(MemberIdentityUser user, string hashedPassword, string providedPassword) { if (user is null) { throw new ArgumentNullException(nameof(user)); } // if there's password config use the base implementation if (!user.PasswordConfig.IsNullOrWhiteSpace()) { return(base.VerifyHashedPassword(user, hashedPassword, providedPassword)); } // Else we need to detect what the password is. This will be the case // for upgrades since no password config will exist. byte[] decodedHashedPassword = null; bool isAspNetIdentityHash = false; try { decodedHashedPassword = Convert.FromBase64String(hashedPassword); isAspNetIdentityHash = true; } catch (Exception) { // ignored - decoding throws } // check for default ASP.NET Identity password hash flags if (isAspNetIdentityHash) { if (decodedHashedPassword[0] == 0x00 || decodedHashedPassword[0] == 0x01) { return(base.VerifyHashedPassword(user, hashedPassword, providedPassword)); } throw new InvalidOperationException("unable to determine member password hashing algorith"); } var isValid = LegacyPasswordSecurity.VerifyPassword( Constants.Security.AspNetUmbraco8PasswordHashAlgorithmName, providedPassword, hashedPassword); return(isValid ? PasswordVerificationResult.SuccessRehashNeeded : PasswordVerificationResult.Failed); }
private bool IsSuccessfulLegacyPassword(string hashedPassword, string providedPassword) { if (!string.IsNullOrEmpty(_legacyMachineKeySettings.Value.MachineKeyDecryptionKey)) { try { var decryptedPassword = DecryptLegacyPassword(hashedPassword, _legacyMachineKeySettings.Value.MachineKeyDecryption, _legacyMachineKeySettings.Value.MachineKeyDecryptionKey); return(decryptedPassword == providedPassword); } catch (Exception ex) { _logger.LogError(ex, "Could not decrypt password even that a DecryptionKey is provided. This means the DecryptionKey is wrong."); return(false); } } var result = LegacyPasswordSecurity.VerifyPassword(Constants.Security.AspNetUmbraco8PasswordHashAlgorithmName, providedPassword, hashedPassword); return(result || LegacyPasswordSecurity.VerifyPassword(Constants.Security.AspNetUmbraco4PasswordHashAlgorithmName, providedPassword, hashedPassword)); }
/// <summary> /// Verifies a user's hashed password /// </summary> /// <param name="user"></param> /// <param name="hashedPassword"></param> /// <param name="providedPassword"></param> /// <returns></returns> /// <exception cref="InvalidOperationException">Thrown when the correct hashing algorith cannot be determined</exception> public override PasswordVerificationResult VerifyHashedPassword(MemberIdentityUser user, string hashedPassword, string providedPassword) { if (user is null) { throw new ArgumentNullException(nameof(user)); } var isPasswordAlgorithmKnown = user.PasswordConfig.IsNullOrWhiteSpace() == false && user.PasswordConfig != Constants.Security.UnknownPasswordConfigJson; // if there's password config use the base implementation if (isPasswordAlgorithmKnown) { var result = base.VerifyHashedPassword(user, hashedPassword, providedPassword); if (result != PasswordVerificationResult.Failed) { return(result); } } // We need to check for clear text passwords from members as the first thing. This was possible in v8 :( else if (IsSuccessfulLegacyPassword(hashedPassword, providedPassword)) { return(PasswordVerificationResult.SuccessRehashNeeded); } // Else we need to detect what the password is. This will be the case // for upgrades since no password config will exist. byte[] decodedHashedPassword = null; bool isAspNetIdentityHash = false; try { decodedHashedPassword = Convert.FromBase64String(hashedPassword); isAspNetIdentityHash = true; } catch (Exception) { // ignored - decoding throws } // check for default ASP.NET Identity password hash flags if (isAspNetIdentityHash) { if (decodedHashedPassword[0] == 0x00 || decodedHashedPassword[0] == 0x01) { return(base.VerifyHashedPassword(user, hashedPassword, providedPassword)); } if (isPasswordAlgorithmKnown) { _logger.LogError("Unable to determine member password hashing algorithm"); } else { _logger.LogDebug("Unable to determine member password hashing algorithm, but this can happen when member enters a wrong password, before it has be rehashed"); } return(PasswordVerificationResult.Failed); } var isValid = LegacyPasswordSecurity.VerifyPassword( Constants.Security.AspNetUmbraco8PasswordHashAlgorithmName, providedPassword, hashedPassword); return(isValid ? PasswordVerificationResult.SuccessRehashNeeded : PasswordVerificationResult.Failed); }