programing

ASPNET ID 2.0에서 사용자 사용 안 함

bestprogram 2023. 7. 31. 21:35

ASPNET ID 2.0에서 사용자 사용 안 함

시스템에서 사용자를 삭제하는 대신 사용자를 비활성화하는 방법을 찾고 있습니다. 이는 관련 데이터의 데이터 무결성을 유지하기 위한 것입니다.하지만 ASPNET ID는 계정 삭제만 제공하는 것 같습니다.

새로운 잠금 기능이 있지만 잠금을 제어하여 사용자를 비활성화할 수 있지만 특정 횟수의 잘못된 암호 시도 후에만 사용자를 잠글 수 있습니다.

다른 방법은?

ID 비트가 설치된 사이트를 만들면 "IdentityModels.cs "이라는 파일이 사이트에 나타납니다.이 파일에는 IdentityUser에서 상속되는 ApplicationUser라는 클래스가 있습니다.

// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit https://devblogs.microsoft.com/aspnet/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates/ to learn more.
public class ApplicationUser : IdentityUser

여기를 쉽게 클릭할 수 있도록 댓글에 멋진 링크가 있습니다.

이 자습서에서는 사용자에 대한 사용자 지정 속성을 추가하기 위해 수행해야 하는 작업에 대해 정확하게 설명합니다.

그리고 실제로, 튜토리얼을 보는 것조차 없습니다.

  1. ApplicationUser 클래스에 속성 추가(예:

    공공장소에서?사용 여부{ get; set; }

  2. DB의 AsNetUsers 테이블에 동일한 이름의 열을 추가합니다.

  3. 쾅, 바로 그거야!

이제 계정 컨트롤러에서 다음과 같은 등록 작업이 수행됩니다.

public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { UserName = model.Email, Email = model.Email, IsEnabled = true };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)

ApplicationUser 개체를 만들 때 IsEnabled = true를 추가했습니다.이제 값이 AsNetUsers 테이블의 새 열에 유지됩니다.

그런 다음 ApplicationSignInManager에서 PasswordSignInAsync를 재정의하여 로그인 프로세스의 일부로 이 값을 확인해야 합니다.

저는 다음과 같이 했습니다.

public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool rememberMe, bool shouldLockout)
    {
        var user = UserManager.FindByEmailAsync(userName).Result;

        if ((user.IsEnabled.HasValue && !user.IsEnabled.Value) || !user.IsEnabled.HasValue)
        {
            return Task.FromResult<SignInStatus>(SignInStatus.LockedOut);
        }

        return base.PasswordSignInAsync(userName, password, rememberMe, shouldLockout);
    }

마일리지는 다양할 수 있으며, 해당 SignIn Status를 반환하고 싶지 않을 수도 있지만, 이해할 수 있습니다.

은 " " 입니다.LockoutEnabledUser사용자가 현재 잠겨 있는지 여부를 나타내는 속성이 아닙니다.가 한 AccessFailedCount에 합니다.MaxFailedAccessAttemptsBeforeLockoutvalue.를 값 차단하는 일 뿐입니다.LockedoutEnddateUtc 중단하려면 속성을 사용해야 따라서 사용자 계정을 영구적으로 사용하지 않도록 설정하거나 일시 중단하려면 사용자 고유의 플래그 속성을 도입해야 할 수 있습니다.

사용자 지정 속성을 생성할 필요가 없습니다.비결은 다음을 설정하는 것입니다.LockoutEnabled 의 속성 및 합니다.LockoutoutEndDateUtc사용자를 잠그기 위해 코드에서 미래 날짜까지.그리고 나서, 전화를 겁니다.UserManager.IsLockedOutAsync(user.Id합니다. ) false를 반환합니다.

다 둘다LockoutEnabled그리고.LockoutoutEndDateUtc사용자를 잠그려면 실제 날짜 및 미래 날짜 기준을 충족해야 합니다.예를 들어, 다음과 같은 경우.LockoutoutEndDateUtc은 은입니다.2014-01-01 00:00:00.000그리고.LockoutEnabled이라true을 부르기UserManager.IsLockedOutAsync(user.Id)여전히 돌아올 것입니다.trueMicrosoft에서 사용자가 잠기는 시간에 대한 시간 범위를 설정할 수 있도록 이러한 방법을 설계한 이유를 알 수 있습니다.

하지만, 나는 그것이 되어야 한다고 주장할 것입니다.LockoutEnabled이라true 합니다.LockoutoutEndDateUtcNULL이거나 이후 날짜입니다.두 속성을 설정하는 가 없습니다.LockoutoutEndDateUtc이라NULL기본값).당신은 그냥 설정할 수 있습니다.LockoutEnabledtrue그리고 만약에LockoutoutEndDateUtc이라NULL사용자가 무기한으로 잠겼습니다.

사용자 지정 IdentityUser 파생 클래스에 사용자 고유의 플래그를 삽입하고 사용/사용 안 함 및 사용자가 사용하지 않을 경우 로그인하지 못하도록 하는 사용자 고유의 논리를 구현/시행해야 합니다.

제가 실제로 한 일은 이것뿐입니다.

    var lockoutEndDate = new DateTime(2999,01,01);
    UserManager.SetLockoutEnabled(userId,true);
    UserManager.SetLockoutEndDate(userId, lockoutEndDate);

이는 기본적으로 잠금을 사용 가능으로 설정하는 것입니다(기본적으로 이 작업을 아직 수행하지 않은 경우). 잠금 종료 날짜를 먼 값으로 설정합니다.

Ozz가 맞지만 기본 클래스를 보고 모든 사인 각도에 대해 확인할 수 있는 방법을 찾는 것이 좋을 수 있습니다. CanSignIn일 수도 있다고 생각합니다.

MS가 오픈 소스이기 때문에 이제 MS의 구현을 확인할 수 있습니다.

https://github.com/aspnet/AspNetCore/blob/master/src/Identity/src/Identity/SignInManager.cs

(URL이 다음으로 변경됨:

https://github.com/aspnet/AspNetCore/blob/master/src/Identity/Core/src/SignInManager.cs)

    public class CustomSignInManager : SignInManager<ApplicationUser>  
{
    public CustomSignInManager(UserManager<ApplicationUser> userManager,
        IHttpContextAccessor contextAccessor,
        IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory,
        IOptions<IdentityOptions> optionsAccessor,
        ILogger<SignInManager<ApplicationUser>> logger,
        IAuthenticationSchemeProvider schemes) : base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes)
    {

    }


    public override async Task<bool> CanSignInAsync(ApplicationUser user)
    {
        if (Options.SignIn.RequireConfirmedEmail && !(await UserManager.IsEmailConfirmedAsync(user)))
        {
            Logger.LogWarning(0, "User {userId} cannot sign in without a confirmed email.", await UserManager.GetUserIdAsync(user));
            return false;
        }
        if (Options.SignIn.RequireConfirmedPhoneNumber && !(await UserManager.IsPhoneNumberConfirmedAsync(user)))
        {
            Logger.LogWarning(1, "User {userId} cannot sign in without a confirmed phone number.", await UserManager.GetUserIdAsync(user));
            return false;
        }

        if (UserManager.FindByIdAsync(user.Id).Result.IsEnabled == false)
        {
            Logger.LogWarning(1, "User {userId} cannot sign because it's currently disabled", await UserManager.GetUserIdAsync(user));
            return false;
        }

        return true;
    }
}

또한 CanSignIn을 호출하는 PreSignInCheck를 재정의하는 것도 고려해 보십시오.

protected virtual async Task<SignInResult> PreSignInCheck(TUser user)
        {
            if (!await CanSignInAsync(user))
            {
                return SignInResult.NotAllowed;
            }
            if (await IsLockedOut(user))
            {
                return await LockedOut(user);
            }
            return null;
        }

이 클래스를 사용할 수 있습니다...ASP의 깨끗한 구현.NET ID...내 코드야.기본 키에 대한 int는 기본 키에 대한 다른 유형을 원한다면 변경할 수 있습니다.

IdentityConfig.cs

public class ApplicationUserManager : UserManager<ApplicationUser, int>
{
    public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
        : base(store)
    {
    }
    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<ApplicationContext>()));
        manager.UserValidator = new UserValidator<ApplicationUser, int>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };
        manager.UserLockoutEnabledByDefault = false;
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider =
                new DataProtectorTokenProvider<ApplicationUser, int>(
                    dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}
public class ApplicationSignInManager : SignInManager<ApplicationUser, int>
{
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) :
        base(userManager, authenticationManager) { }
    public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
    {
        return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
    }
    public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
    {
        return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
    }
}
public class ApplicationRoleManager : RoleManager<ApplicationRole, int>
{
    public ApplicationRoleManager(IRoleStore<ApplicationRole, int> store)
        : base(store)
    {
    }
}
public class ApplicationRoleStore : RoleStore<ApplicationRole, int, ApplicationUserRole>
{
    public ApplicationRoleStore(ApplicationContext db)
        : base(db)
    {
    }
}
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, int,
ApplicationLogin, ApplicationUserRole, ApplicationClaim>
{
    public ApplicationUserStore(ApplicationContext db)
        : base(db)
    {
    }
}

IdentityModel.cs

public class ApplicationUser : IdentityUser<int, ApplicationLogin, ApplicationUserRole, ApplicationClaim>
{   
    //your property 
    //flag for users state (active, deactive or enabled, disabled)
    //set it false to disable users
    public bool IsActive { get; set; }
    public ApplicationUser()
    {
    }
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}
public class ApplicationUserRole : IdentityUserRole<int>
{
}
public class ApplicationLogin : IdentityUserLogin<int>
{
    public virtual ApplicationUser User { get; set; }
}
public class ApplicationClaim : IdentityUserClaim<int>
{
    public virtual ApplicationUser User { get; set; }
}
public class ApplicationRole : IdentityRole<int, ApplicationUserRole>
{
    public ApplicationRole()
    {
    }
}
public class ApplicationContext : IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationLogin, ApplicationUserRole, ApplicationClaim>
{
    //web config connectionStringName DefaultConnection change it if required
    public ApplicationContext()
        : base("DefaultConnection")
    {
        Database.SetInitializer<ApplicationContext>(new CreateDatabaseIfNotExists<ApplicationContext>());
    }
    public static ApplicationContext Create()
    {
        return new ApplicationContext();
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    }
}  

SignInManager에 string userName 대신 TUser 사용자를 받아들이는 다른 공용 메서드가 있으므로 Watson을 업데이트했습니다.승인된 답변은 사용자 이름 서명으로 메서드를 재정의하는 것만 제안합니다.둘 다 재정의해야 합니다. 그렇지 않으면 비활성화된 사용자에게 서명할 수 있습니다.기본 구현의 두 가지 방법은 다음과 같습니다.

public virtual async Task<SignInResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure)
{
  var user = await UserManager.FindByNameAsync(userName);
  if (user == null)
  {
    return SignInResult.Failed;
  }

  return await PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure);
}

public virtual async Task<SignInResult> PasswordSignInAsync(User user, string password, bool isPersistent, bool lockoutOnFailure)
{
  if (user == null)
  {
    throw new ArgumentNullException(nameof(user));
  }

  var attempt = await CheckPasswordSignInAsync(user, password, lockoutOnFailure);
  return attempt.Succeeded
      ? await SignInOrTwoFactorAsync(user, isPersistent)
      : attempt;
}

CanSignIn을 재정의하는 것은 CheckPasswordSignInAsync에서 호출되는 PreSignInCheck에 의해 호출되기 때문에 저에게 더 나은 해결책인 것 같습니다.소스에서 알 수 있는 바로는 CanSignIn을 재정의하는 것이 모든 시나리오를 포괄해야 합니다.다음은 사용할 수 있는 간단한 구현입니다.

public override async Task<bool> CanSignInAsync(User user)
{
  var canSignIn = user.IsEnabled;

  if (canSignIn) { 
    canSignIn = await base.CanSignInAsync(user);
  }
  return canSignIn;
}

asp.net Core Identity v3에는 사용자의 로그인을 방지하는 새로운 방법이 추가되었습니다.이전에는 계정에 확인된 전자 메일 주소 또는 전화 번호가 있어야 했지만, 이제는 지정할 수 있습니다..RequireConfirmedAccount의 기본 구현IUserConfirmation<>서비스는 확인된 전자 메일 주소를 요구하는 것과 동일하게 동작하며, 확인이 의미하는 바를 정의하기 위한 자체 서비스를 제공합니다.

    public class User : IdentityUser<string>{
        public bool IsEnabled { get; set; }
    }

    public class UserConfirmation : IUserConfirmation<User>
    {
        public Task<bool> IsConfirmedAsync(UserManager<User> manager, User user) => 
            Task.FromResult(user.IsEnabled);
    }

    services.AddScoped<IUserConfirmation<User>, UserConfirmation>();
    services.AddIdentity<User, IdentityRole>(options => { 
        options.SignIn.RequireConfirmedAccount = true;
    } );

ID를 제거하려면 자체 UserStore를 구현해야 합니다.

또한 이것은 당신에게 도움이 될 것입니다.

언급URL : https://stackoverflow.com/questions/22652118/disable-user-in-aspnet-identity-2-0