Last active
March 27, 2019 02:26
-
-
Save theuntitled/3561ac32a5e2d79fe505963a87382dc0 to your computer and use it in GitHub Desktop.
IdentitityFramework 2 Custom SHA256 IPasswordHasher with Salt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment