Saturday, Jul 21, 2018
Delegates in action, part 2: ASP.NET password encryption
This blog describes a simple centralized approach to paging which can be found here. Our goal is to change the ASP.NET membership password format (more regarding asp.net membership password formats can be found here).
The problem
Setting the password formats in ASP.Net is quite simple. All you need to do is to set a single setting in your web.config and you are ready to go. But what if you’ve already used Clear password format, your application is in a production environment, and you decide to change it to the Hashed password format? You cannot just change the PasswordFormat setting and expect that everything will work fine. You have to care of the old entries and convert them to the new password format.
Implementation
Since our paging method accepts two delegates, we need to implement two methods for performing an action on entity and fetching the entities from the database. As always, we will be using the LLBLGen ORM tool for database access.
Action method:
public void PerformPasswordChange(IEntity2 entity, UnitOfWork2 uow)
{
AspnetUsersEntity user = (AspnetUsersEntity)entity;
ChangeUserPassword(user, user.AspnetMembership.Password);
uow.AddForSave(entity);
}
Fetching the entities from the database:
public IEntityCollection2 GetUsersForPasswordFormatChange(int currentPageIndex, int pageSize, out int recordCount
{
EntityCollection
IRelationPredicateBucket bucket = new RelationPredicateBucket();
bucket.Relations.Add(AspnetUsersEntity.Relations.AspnetMembershipEntityUsingUserId);
bucket.PredicateExpression.Add(AspnetMembershipFields.PasswordFormat == 0);
PrefetchPath2 path = new PrefetchPath2(EntityType.AspnetUsersEntity);
path.Add(AspnetUsersEntity.PrefetchPathAspnetMembership);
recordCount = GenericRepository.GetInstance().GetDbCount(col, bucket);
if (recordCount > 0)
{
GenericRepository.GetInstance().FetchEntityCollection(col, bucket, 0, null, path, currentPageIndex, pageSize);
return col;
}
else
return null;
}
Here is an additional password helper method that does the actual work:
private bool ChangeUserPassword(AspnetUsersEntity entity, string password)
{
if (entity.AspnetMembership != null && !String.IsNullOrEmpty(password))
{
entity.AspnetMembership.PasswordFormat = Convert.ToInt32(Membership.Provider.PasswordFormat);
entity.AspnetMembership.PasswordSalt = Membership.Provider.CreateSalt();
entity.AspnetMembership.Password =
Membership.Provider.EncodePassword(Membership.Provider.PasswordFormat, password,
entity.AspnetMembership.PasswordSalt);
return true;
}
else
return false;
}
Once we have required methods implemented, we can simply call the paging worker method as follows:
PagingWorker.DoWorkWithPaging(GetUsersForPasswordFormatChange, PerformPasswordChange);
Summary
In the previous post we have implemented a simple centralized worker method. Now we were able to see how it works in a real time example. You can also use it for other MonoX entities(UserProfile, Calendar, etc).
We strongly recommend you to make a database backup before you start playing either with password format conversion or some other data manipulation task.