2017-10-24 1 views
0

Helloes, 신원 - 사용자 정의 사용자는

내가 Identity와 .NetCore MVC APP을 가지고 있고 사용자 정의 사용자 유효성 검사기를 만들 수 있었다 this 가이드를 사용하여 검증.

public class UserDomainValidator<TUser> : IUserValidator<TUser> 
     where TUser : IdentityUser 
{ 
    private readonly List<string> _allowedDomains = new List<string> 
    { 
     "elanderson.net", 
     "test.com" 
    }; 

    public Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, 
               TUser user) 
    { 
     if (_allowedDomains.Any(allowed => 
       user.Email.EndsWith(allowed, StringComparison.CurrentCultureIgnoreCase))) 
     { 
      return Task.FromResult(IdentityResult.Success); 
     } 

     return Task.FromResult(
       IdentityResult.Failed(new IdentityError 
       { 
        Code = "InvalidDomain", 
        Description = "Domain is invalid." 
       })); 
    } 
} 

하고 성공적으로이

services.AddIdentity<ApplicationUser, IdentityRole>(options => 
{ 
    options.User.AllowedUserNameCharacters = "abccom."; 
    options.User.RequireUniqueEmail = true; 
}) 
    .AddEntityFrameworkStores<ApplicationDbContext>() 
    .AddDefaultTokenProviders() 
    .AddUserValidator<UserDomainValidator<ApplicationUser>>(); 

이제 DI에 내 ID 서비스에 추가하여 내 사용자 생성을 확인, 신원의 one of the existing validatiors는 사용자 이름에서부터

private async Task ValidateUserName(UserManager<TUser> manager, TUser user, ICollection<IdentityError> errors) 
    { 
     var userName = await manager.GetUserNameAsync(user); 
     if (string.IsNullOrWhiteSpace(userName)) 
     { 
      errors.Add(Describer.InvalidUserName(userName)); 
     } 
     else if (!string.IsNullOrEmpty(manager.Options.User.AllowedUserNameCharacters) && 
      userName.Any(c => !manager.Options.User.AllowedUserNameCharacters.Contains(c))) 
     { 
      errors.Add(Describer.InvalidUserName(userName)); 
     } 
     else 
     { 
      var owner = await manager.FindByNameAsync(userName); 
      if (owner != null && 
       !string.Equals(await manager.GetUserIdAsync(owner), await manager.GetUserIdAsync(user))) 
      { 
       errors.Add(Describer.DuplicateUserName(userName)); 
      } 
     } 
    } 

고유해야한다고 내 애플 리케이션 내 로그인은 임차인 + 사용자 이름/임차인 + 이메일을 통해 이루어집니다, 나는 중복 된 사용자 이름을 허용하고 싶습니다 ... 비슷한 일을 한 사람이나 아이디어가 있습니까?

나는이 검증을 제거해야하고 나는 그것이 올바른 사용자 로그인 할 수 있도록 SignInManager 또는 무언가에 적응하는 것 같아요 ..

답변

1

대신 새로운 검증 서비스에서 추가를 대체하고 직접 만들 추가 UserValidator.

services.Replace(ServiceDescriptor.Scoped<IUserValidator<User>, CustomUserValidator<User>>()); 


    public class CustomUserValidator<TUser> : IUserValidator<TUser> where TUser : class 
    { 

    private readonly List<string> _allowedDomains = new List<string> 
    { 
     "elanderson.net", 
     "test.com" 
    }; 

    public CustomUserValidator(IdentityErrorDescriber errors = null) 
    { 
     Describer = errors ?? new IdentityErrorDescriber(); 
    } 

    public IdentityErrorDescriber Describer { get; } 


    public virtual async Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, TUser user) 
    { 
     if (manager == null) 
      throw new ArgumentNullException(nameof(manager)); 
     if (user == null) 
      throw new ArgumentNullException(nameof(user)); 
     var errors = new List<IdentityError>(); 
     await ValidateUserName(manager, user, errors); 
     if (manager.Options.User.RequireUniqueEmail) 
      await ValidateEmail(manager, user, errors); 
     return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success; 
    } 

    private async Task ValidateUserName(UserManager<TUser> manager, TUser user, ICollection<IdentityError> errors) 
    { 
     var userName = await manager.GetUserNameAsync(user); 
     if (string.IsNullOrWhiteSpace(userName)) 
      errors.Add(Describer.InvalidUserName(userName)); 
     else if (!string.IsNullOrEmpty(manager.Options.User.AllowedUserNameCharacters) && userName.Any(c => !manager.Options.User.AllowedUserNameCharacters.Contains(c))) 
     { 
      errors.Add(Describer.InvalidUserName(userName)); 
     } 
    } 

    private async Task ValidateEmail(UserManager<TUser> manager, TUser user, List<IdentityError> errors) 
    { 
     var email = await manager.GetEmailAsync(user); 
     if (string.IsNullOrWhiteSpace(email)) 
      errors.Add(Describer.InvalidEmail(email)); 
     else if (!new EmailAddressAttribute().IsValid(email)) 
     { 
      errors.Add(Describer.InvalidEmail(email)); 
     } 
     else if (_allowedDomains.Any(allowed => 
      email.EndsWith(allowed, StringComparison.CurrentCultureIgnoreCase))) 
     { 
      errors.Add(new IdentityError 
      { 
       Code = "InvalidDomain", 
       Description = "Domain is invalid." 
      }); 
     } 
     else 
     { 
      var byEmailAsync = await manager.FindByEmailAsync(email); 
      var flag = byEmailAsync != null; 
      if (flag) 
      { 
       var a = await manager.GetUserIdAsync(byEmailAsync); 
       flag = !string.Equals(a, await manager.GetUserIdAsync(user)); 
      } 
      if (!flag) 
       return; 
      errors.Add(Describer.DuplicateEmail(email)); 
     } 
    } 
    } 
+0

서비스에 대해 몰랐습니다. 실제로 이것은 매우 좋은 아이디어이며 매우 간단합니다! 솔루션 및 시간 내 주셔서 감사합니다! ;) –

+0

당신이 가장 환영합니다 –

관련 문제