Will the new middleware stuff in Startup.Auth.cs and IdentityModels.cs make it to the RTM package of the ASP.NET Identity components?

Jan 29, 2014 at 2:05 PM
Edited Jan 29, 2014 at 2:06 PM
Hi, I'm currently building an e-commerce site using ASP.NET MVC 5 and ASP.NET Identity 2.0.0 alpha. As the final release of the site is planned for spring of 2014 I wish for that I will not be forced to redesign all the middleware stuff (I am using an AccountManager wrapper class for two of my controllers that both use the Login/Register functionality of the ASP.NET Identity Visual Studio 2013 templates which adds complexity to how the UserManager is accessed).

I am in particular referring to these two pieces of code:
  1. https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/Identity-PasswordPolicy/Identity-PasswordPolicy/App_Start/Startup.Auth.cs
        // Configure the UserManager
        app.UseUserManagerFactory(new IdentityFactoryOptions<ApplicationUserManager>()
        {
            DataProtectionProvider = app.GetDataProtectionProvider(),
            Provider = new IdentityFactoryProvider<ApplicationUserManager>()
            {
                OnCreate = ApplicationUserManager.Create
            }
        });
    
    
  2. https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/Identity-PasswordPolicy/Identity-PasswordPolicy/Models/IdentityModels.cs


    public class ApplicationUserManager : UserManager<ApplicationUser>
    {
    private readonly int PASSWORD_HISTORY_LIMIT = 5;
    
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }
    
    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options)
    {
        var manager = new ApplicationUserManager(new ApplicationUserStore(new ApplicationDbContext()));
        // Configure the application user manager
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        manager.PasswordValidator = new CustomPasswordValidator(10);
    
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.PasswordResetTokens = new DataProtectorTokenProvider(dataProtectionProvider.Create("PasswordReset"));
            manager.UserConfirmationTokens = new DataProtectorTokenProvider(dataProtectionProvider.Create("ConfirmUser"));
        }
        return manager;
    }
    
    public override async Task<IdentityResult> ChangePasswordAsync(string userId, string currentPassword, string newPassword)
    {
        if (await IsPreviousPassword(userId, newPassword))
        {
            return await Task.FromResult(IdentityResult.Failed("Cannot reuse old password"));
        }
        var result = await base.ChangePasswordAsync(userId, currentPassword, newPassword);
        if (result.Succeeded)
        {
            var store = Store as ApplicationUserStore;
    
            await store.AddToPreviousPasswordsAsync(await FindByIdAsync(userId), PasswordHasher.HashPassword(newPassword));
        }
        return result;
    }
    
    
    public override async Task<IdentityResult> ResetPasswordAsync(string userId, string token, string newPassword)
    {
        if (await IsPreviousPassword(userId, newPassword))
        {
            return await Task.FromResult(IdentityResult.Failed("Cannot reuse old password"));
        }
        var result = await base.ResetPasswordAsync(userId, token, newPassword);
        if (result.Succeeded)
        {
            var store = Store as ApplicationUserStore;
            await store.AddToPreviousPasswordsAsync(await FindByIdAsync(userId), PasswordHasher.HashPassword(newPassword));
        }
        return result;
    }
    
    
    private async Task<bool> IsPreviousPassword(string userId, string newPassword)
    {
        var user = await FindByIdAsync(userId);
        if (user.PreviousUserPasswords.OrderByDescending(x => x.CreateDate).
        Select(x => x.PasswordHash).Take(PASSWORD_HISTORY_LIMIT).Where(x => PasswordHasher.VerifyHashedPassword(x, newPassword) != PasswordVerificationResult.Failed).
        Any())
        {
            return true;
        }
        return false;
    } 
    }
So my concern and question is: Will this code make it to the RTM package/Visual Studio 2013 templates so that I can continue working with the ASP.NET Identity 2.0.0 alpha components in my e-commerce site that is going live soon?

Thanks!

/P
Developer
Jan 29, 2014 at 8:32 PM
@PussInBoots: Some of the code you have will be changed in the upcoming release. You can try the beta package from the nightly feed http://myget.org/f/aspnetwebstacknightly. To summarize the changes
  • UseUSerManagerFactory is replaced with CreatePerOwinContext
  • ApplicationUserManager.Create takes an additional method parameter of type IOwinContext
  • The PasswordResetTokens and UserConfirmationTokens property is replaced with a single property in the UserManager.
This is a quick heads up based on your requirement which might make to the RTM build. I'll update the samples on the codeplex site with the beta package once it is released.
Jan 31, 2014 at 8:23 AM
Thanks for the info!