简体   繁体   中英

custom password policy using ASP.NET Identity 3

Asp.NET identity 3 removed the one-argument constructor for UserManager so I have to specify, when inheriting from UserManager, all the 10 arguments. Because of the simple task i've to achive I wrote this code:

public class AppUserManager : UserManager<ApplicationUser>
{
    public AppUserManager() : base(new UserStore<ApplicationUser>(new AppDbContext()), null, null, null, new PasswordValidator[] { new PasswordValidator() }, null, null, null, null, null)
    {

    }
}

public class PasswordValidator : IPasswordValidator<ApplicationUser>
{
    public Task<IdentityResult> ValidateAsync(UserManager<ApplicationUser> manager, ApplicationUser user, string password)
    {
        return Task.Run(() =>
        {
            if (password.Length >= 4) return IdentityResult.Success;
            else { return IdentityResult.Failed(new IdentityError { Code = "SHORTPASSWORD", Description = "Password too short" }); }
        });
    }
}

I suppose this doesn't work because when i call the controller:

    [HttpPost]
    public async Task<dynamic> Post([FromBody] RegisterSchema req)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser(req.username);
            AppUserManager um = new AppUserManager();
            var result = await um.CreateAsync(user, req.password);
            return result;
        }

result is always null (while um seems to be correctly istances)

It may be because you're putting so many nulls in the constructor. Here's the constructor I use for my UserManager overrides.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.OptionsModel;

namespace [YourApp].Services
{
    public class ApplicationUserManager : UserManager<ApplicationUser>
    {
        public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationUser> passwordHasher,
                                      IEnumerable<IUserValidator<ApplicationUser>> userValidators, IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators,
                                      ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger,
                                      IHttpContextAccessor contextAccessor)
        : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger, contextAccessor)
        {

        }
    }
}

The previous answer works well. I attach my version for who need the complete model:

public class AppUserManager : UserManager<ApplicationUser>
{
    public AppUserManager(IServiceProvider services, IHttpContextAccessor contextAccessor, ILogger<UserManager<ApplicationUser>> logger) : base(new UserStore<ApplicationUser>(new ApplicationDbContext()), new CustomOptions(), new PasswordHasher<ApplicationUser>(), new UserValidator<ApplicationUser>[] { new UserValidator<ApplicationUser>() }, new PasswordValidator[] { new PasswordValidator() }, new UpperInvariantLookupNormalizer(), new IdentityErrorDescriber(), services, logger, contextAccessor) 
    {
    }
}

public class PasswordValidator : IPasswordValidator<ApplicationUser>
{
    public Task<IdentityResult> ValidateAsync(UserManager<ApplicationUser> manager, ApplicationUser user, string password)
    {
        return Task.Run(() =>
        {
            if (password.Length >= 4) return IdentityResult.Success;
            else { return IdentityResult.Failed(new IdentityError { Code = "SHORTPASSWORD", Description = "Password too short" }); }
        });
    }
}

public class CustomOptions : IOptions<IdentityOptions>
{
    public IdentityOptions Value { get; private set; }
    public CustomOptions()
    {
        Value = new IdentityOptions
        {
            ClaimsIdentity = new ClaimsIdentityOptions(),
            Cookies = new IdentityCookieOptions(),
            Lockout = new LockoutOptions(),
            Password = null,
            User = new UserOptions(),
            SignIn = new SignInOptions(),
            Tokens = new TokenOptions()
        };
    }       
}

You can inject the service in your ConfigureServices():

        services.AddScoped<AppUserManager>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM