IdentitityFramework 2 Custom SHA256 IPasswordHasher with Salt
CustomPasswordHasher.cs
using System;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNet.Identity;
namespace Project
{
public class CustomPasswordHasher<TUser> : ICustomPasswordHasher<TUser> where TUser : class , IUser<string>
{
public string HashPassword( string password )
{
throw new NotSupportedException();
}
public PasswordVerificationResult VerifyHashedPassword( string hashedPassword , string providedPassword )
{
throw new NotSupportedException();
}
public string HashPassword( string password , TUser user )
{
var sha256 = new SHA256Managed();
var hashBytes = sha256.ComputeHash( Encoding.UTF8.GetBytes( string.Concat( password , user.UserName ) ) );
var hash = new StringBuilder();
foreach ( var hashByte in hashBytes )
{
hash.Append( hashByte.ToString( "x2" ) );
}
return hash.ToString();
}
public PasswordVerificationResult VerifyHashedPassword( string hashedPassword , string providedPassword , TUser user )
{
return HashPassword( providedPassword , user ) == hashedPassword
? PasswordVerificationResult.Success
: PasswordVerificationResult.Failed;
}
}
}
ICustomPasswordHasher.cs
using Microsoft.AspNet.Identity;
namespace Project
{
public interface ICustomPasswordHasher<in TUser> : IPasswordHasher where TUser : class , IUser<string>
{
string HashPassword( string password , TUser user );
PasswordVerificationResult VerifyHashedPassword( string hashedPassword , string providedPassword , TUser user );
}
}
UserManager.cs
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security.DataProtection;
namespace Project
{
public class UserManager : UserManager<ApplicationUser> , IUserManager
{
public UserManager( IUserStore<ApplicationUser> store ) : base( store )
{
UserValidator = new UserValidator<ApplicationUser>( this ) {
RequireUniqueEmail = true ,
AllowOnlyAlphanumericUserNames = true
};
PasswordValidator = new PasswordValidator {
RequiredLength = 8 ,
RequireDigit = true ,
RequireLowercase = true ,
RequireUppercase = true ,
RequireNonLetterOrDigit = true
};
PasswordHasher = new CustomPasswordHasher<ApplicationUser>();
UserLockoutEnabledByDefault = false;
if ( DefaultDataProtectionProvider != null )
{
UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>( DefaultDataProtectionProvider.Create( "ASP.NET Identity" ) );
}
}
public static IDataProtectionProvider DefaultDataProtectionProvider { get; set; }
private CustomPasswordHasher<ApplicationUser> GetPasswordHasher()
{
return PasswordHasher as CustomPasswordHasher<ApplicationUser>;
}
private IUserSecurityStampStore<ApplicationUser, string> GetSecurityStore()
{
var securityStampStore = Store as IUserSecurityStampStore<ApplicationUser, string>;
if ( securityStampStore == null )
{
throw new NotSupportedException("Store does not implement IUserSecurityStampStore<ApplicationUser>");
}
return securityStampStore;
}
protected override async Task<bool> VerifyPasswordAsync( IUserPasswordStore<ApplicationUser , string> store ,
ApplicationUser user ,
string password )
{
var hash = await store.GetPasswordHashAsync( user );
return GetPasswordHasher().VerifyHashedPassword( hash , password , user ) != PasswordVerificationResult.Failed;
}
protected override async Task<IdentityResult> UpdatePassword( IUserPasswordStore<ApplicationUser , string> passwordStore , ApplicationUser user , string newPassword )
{
var validationResult = await PasswordValidator.ValidateAsync( newPassword );
if ( !validationResult.Succeeded )
{
return validationResult;
}
await passwordStore.SetPasswordHashAsync( user , GetPasswordHasher().HashPassword( newPassword , user ) );
await GetSecurityStore().SetSecurityStampAsync( user , Guid.NewGuid().ToString() );
return IdentityResult.Success;
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(
ApplicationUser user ,
string authenticationType = DefaultAuthenticationTypes.ApplicationCookie )
{
var identity = await CreateIdentityAsync( user , authenticationType );
identity.AddClaim( new Claim( ClaimTypes.Email , user.Email ) );
return identity;
}
}
}