Created
May 10, 2013 23:36
-
-
Save robertmclaws/5558238 to your computer and use it in GitHub Desktop.
Code to use SimpleMembership if your logins are encrypted and not hashed. Works in conjunction with the concepts and Account Controller code outlined at http://pretzelsteelersfan.blogspot.com/2012/11/migrating-legacy-apps-to-new.html
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.Text; | |
using System.Web.Security; | |
namespace AdvancedREI.Providers | |
{ | |
public class DecryptingSqlMembershipProvider : SqlMembershipProvider | |
{ | |
/// <summary> | |
/// Allows public access to protected member | |
/// </summary> | |
/// <param name="encodedPassword"></param> | |
/// <returns></returns> | |
public new byte[] DecryptPassword(byte[] encodedPassword) | |
{ | |
return base.DecryptPassword(encodedPassword); | |
} | |
/// <summary> | |
/// Allows public access to protected member | |
/// </summary> | |
/// <param name="password"></param> | |
/// <returns></returns> | |
public string DecryptPassword(string encryptedPassword) | |
{ | |
var bytes = DecryptPassword(Convert.FromBase64String(encryptedPassword)); | |
return Encoding.Unicode.GetString(bytes, 0x10, bytes.Length - 0x10); | |
} | |
/// <summary> | |
/// Allows public access to protected member | |
/// </summary> | |
/// <param name="password"></param> | |
/// <returns></returns> | |
public new byte[] EncryptPassword(byte[] password) | |
{ | |
return base.EncryptPassword(password); | |
} | |
/// <summary> | |
/// Allows public access to protected member | |
/// </summary> | |
/// <param name="password"></param> | |
/// <returns></returns> | |
public string EncryptPassword(string password) | |
{ | |
return Convert.ToBase64String(EncryptPassword(ASCIIEncoding.ASCII.GetBytes(password))); | |
} | |
} | |
} |
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.Linq; | |
using System.Security.Cryptography; | |
using System.Text; | |
using System.Web.Security; | |
namespace AdvancedREI.Security | |
{ | |
public class LegacySecurity | |
{ | |
/// <summary> | |
/// The user's profile record. | |
/// </summary> | |
private UserProfile _userProfile; | |
/// <summary> | |
/// The users membership record. | |
/// </summary> | |
private webpages_Membership _membership; | |
/// <summary> | |
/// The clear text password. | |
/// </summary> | |
private string _clearPassword; | |
/// <summary> | |
/// The password after it has been hashed using SHA1. | |
/// </summary> | |
private string _sha1HashedPassword; | |
/// <summary> | |
/// The password after it has been hashed using SHA1. | |
/// </summary> | |
private string _decryptedPassword; | |
/// <summary> | |
/// The user's user name. | |
/// </summary> | |
private string _userName; | |
/// <summary> | |
/// Indicates if the authentication token in the cookie should be persisted beyond the current session. | |
/// </summary> | |
private bool _persistCookie; | |
/// <summary> | |
/// Validates the user against legacy values. | |
/// </summary> | |
/// <param name="userName">The user's UserName.</param> | |
/// <param name="password">The user's password.</param> | |
/// <param name="persistCookie">Indicates if the authentication token in the cookie should be persisted beyond the current session.</param> | |
/// <returns>true if the user is validated and logged in, otherwise false.</returns> | |
public bool Login(string userName, string password, bool persistCookie = false) | |
{ | |
this._userName = userName; | |
this._clearPassword = password; | |
this._persistCookie = persistCookie; | |
if (!GetOriginalValues()) | |
{ | |
return false; | |
} | |
SetHashedPassword(); | |
var provider = Membership.Providers["Decrypting"] as DecryptingSqlMembershipProvider; | |
_decryptedPassword = provider.DecryptPassword(_membership.Password); | |
var isEncrypted = _decryptedPassword == _clearPassword; | |
if (this._sha1HashedPassword != this._membership.Password && !isEncrypted) | |
{ | |
return false; | |
} | |
this.SetPasswordAndLoginUser(); | |
return true; | |
} | |
/// <summary> | |
/// Gets the original password values | |
/// </summary> | |
protected bool GetOriginalValues() | |
{ | |
using (var context = new UsersContext()) | |
{ | |
this._userProfile = context.UserProfiles.SingleOrDefault(x => x.ProviderUserName.ToLower() == _userName.ToLower()); | |
if (this._userProfile == null) | |
{ | |
return false; | |
} | |
this._membership = context.Memberships.SingleOrDefault(x => x.UserId == this._userProfile.ProviderUserId); | |
if (this._membership == null) | |
{ | |
return false; | |
} | |
if (!this._membership.IsConfirmed) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
/// <summary> | |
/// Encrypts the password using the SHA1 algorithm. | |
/// </summary> | |
/// <remarks> | |
/// Many thanks to Malcolm Swaine for the hashing code. | |
/// http://www.codeproject.com/Articles/32600/Manually-validating-an-ASP-NET-user-account-with-a | |
/// </remarks> | |
protected void SetHashedPassword() | |
{ | |
byte[] bIn = Encoding.Unicode.GetBytes(_clearPassword); | |
byte[] bSalt = Convert.FromBase64String(_membership.PasswordSalt); | |
byte[] bAll = new byte[bSalt.Length + bIn.Length]; | |
byte[] bRet = null; | |
Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length); | |
Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length); | |
HashAlgorithm s = HashAlgorithm.Create("SHA1"); | |
bRet = s.ComputeHash(bAll); | |
string newHash = Convert.ToBase64String(bRet); | |
this._sha1HashedPassword = newHash; | |
} | |
/// <summary> | |
/// Sets the password using the new algorithm and performs a login. | |
/// </summary> | |
protected void SetPasswordAndLoginUser() | |
{ | |
var token = WebMatrix.WebData.WebSecurity.GeneratePasswordResetToken(this._userName, 2); | |
WebMatrix.WebData.WebSecurity.ResetPassword(token, _clearPassword); | |
WebMatrix.WebData.WebSecurity.Login(_userName, _clearPassword, _persistCookie); | |
} | |
} | |
} |
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
<membership defaultProvider="DefaultMembershipProvider"> | |
<providers> | |
<add name="DefaultMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> | |
<add name="Decrypting" type="AdvancedREI.Providers.DecryptingSqlMembershipProvider, YOURWEBSITEDLL, Version=1.0.0.0, Culture=neutral" connectionStringName="YOURCONNECTIONSTRING" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Encrypted" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" /> | |
</providers> | |
</membership> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment