2015-10-05 45 views
6

私はIdentity 2.0でユーザーを無効にする方法を見つけようとしており、その情報を見つけられないようです。Identity 2.0でユーザーを無効にする方法は?

私は基本的にユーザーをIsActive = falseに設定したいと思います。ユーザーが作成されるとすぐにそれを行うことをお勧めします。しかし、私は私たちのサイト管理者のIsActiveを設定する方法が必要です。私はすでにASP.Netメンバーシップでこれを持っていますが、サイトをMVCとアイデンティティに隠しています。

私の必要条件として、アカウントを登録してアカウントを登録するように求めますが、デフォルトでは無効にします。その後、私たちは入会料を受け取ったときに戻ってそれを可能にします。定期購読が稼働していて、更新されていないときにユーザーを無効にするためにも使用します。

アカウントを削除せずに無効にする方法や、X時間だけロックアウトする方法はありますか?これまでのところ、アイデンティティのユーザーを無効にする方法は見つかっていません。この質問が以前には出てこなかったのは驚きです。

答えて

11

がインストールアイデンティティビットでサイトを作成すると、あなたのサイトは "IdentityModels.cs" と呼ばれるファイルを持っています。このファイルには、IdentityUserから継承するApplicationUserというクラスがあります。

// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. 
public class ApplicationUser : IdentityUser 

がコメントでの素敵なリンクを容易にするためにこのチュートリアルでは正確にあなたがあなたのユーザーのためにカスタムプロパティを追加する何をする必要があるかを説明しますhere

をクリックして、あります。

実際、チュートリアルを見ても気にしないでください。 )

public bool? IsEnabled { get; set; } 

2あなたのDBにAspNetUsersテーブルの上に同じ名前の列を追加します。

1)例えば、ApplicationUserクラスにプロパティを追加します。

3)ブーム、それだけです!次のように

は、今すぐあなたのAccountControllerで、あなたが登録作用を有する:

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 =真を追加しました。値はAspNetUsersテーブルの新しい列に保持されます。

これで、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); 
    } 

あなたの走行距離は異なる場合があり、そしてあなたがSignInStatusことを返すようにしたいかもしれませんが、あなたのアイデアを得ます。

+1

ApplicationSignInManagerまたはPasswordSignInAsync(...)を持たないIdentity 3.0を使用してASP.NET Core 1.0でどのように同じことを達成できますか? – nam

+0

'.Result'を使用することは、推奨事項に反するものであり、特定のシナリオではデッドロックを引き起こすことが知られており、非同期の全ポイントを打ち負かすスレッドもブロックします。 'PasswordSignInAsync'メソッドを' async'とマークし、代わりに 'FindByEmailAsync'を待つ方が良いでしょう。 – TKharaishvili

+1

これの最大の問題は、すでにログインしている場合に影響を与えないことです。特に、「Remember Me」チェックボックスをチェックした場合。彼らが定期的にサイトにアクセスする場合、彼らはログインする必要はありません。私は、既存のロックアウトロジックがこれに使用できるかどうかを把握しようとしています。 。 –

0

ステップ1:IUserLockoutStoreを実装するカスタムユーザーストアを作成します。

 public Task<DateTimeOffset> GetLockoutEndDateAsync(MyUser user) 
    { 
     //.. 
    } 

    public Task SetLockoutEndDateAsync(MyUser user, DateTimeOffset lockoutEnd) 
    { 
     //.. 
    } 

    public Task<int> IncrementAccessFailedCountAsync(MyUser user) 
    { 
     //.. 
    } 

    public Task ResetAccessFailedCountAsync(MyUser user) 
    { 
     //.. 
    } 

    public Task<int> GetAccessFailedCountAsync(MyUser user) 
    { 
     //.. 
    } 

    public Task<bool> GetLockoutEnabledAsync(MyUser user) 
    { 
     //.. 
    } 

    public Task SetLockoutEnabledAsync(MyUser user, bool enabled) 
    { 
     //.. 
    } 
} 

ステップ2:UserManagerではなく、ログイン/ログアウトアクションで次のクラスを使用して、カスタムユーザーストアのインスタンスを渡します。

public class LockingUserManager<TUser, TKey> : UserManager<TUser, TKey> 
    where TUser : class, IUser<TKey> 
    where TKey : IEquatable<TKey> 
{ 
    private readonly IUserLockoutStore<TUser, TKey> _userLockoutStore; 

    public LockingUserManager(IUserLockoutStore<TUser, TKey> store) 
     : base(store) 
    { 
     if (store == null) throw new ArgumentNullException("store"); 

     _userLockoutStore = store; 
    } 

    public override async Task<TUser> FindAsync(string userName, string password) 
    { 
     var user = await FindByNameAsync(userName); 

     if (user == null) return null; 

     var isUserLockedOut = await GetLockoutEnabled(user); 

     if (isUserLockedOut) return user; 

     var isPasswordValid = await CheckPasswordAsync(user, password); 

     if (isPasswordValid) 
     { 
      await _userLockoutStore.ResetAccessFailedCountAsync(user); 
     } 
     else 
     { 
      await IncrementAccessFailedCount(user); 

      user = null; 
     } 

     return user; 
    } 

    private async Task<bool> GetLockoutEnabled(TUser user) 
    { 
     var isLockoutEnabled = await _userLockoutStore.GetLockoutEnabledAsync(user); 

     if (isLockoutEnabled == false) return false; 

     var shouldRemoveLockout = DateTime.Now >= await _userLockoutStore.GetLockoutEndDateAsync(user); 

     if (shouldRemoveLockout) 
     { 
      await _userLockoutStore.ResetAccessFailedCountAsync(user); 

      await _userLockoutStore.SetLockoutEnabledAsync(user, false); 

      return false; 
     } 

     return true; 
    } 

    private async Task IncrementAccessFailedCount(TUser user) 
    { 
     var accessFailedCount = await _userLockoutStore.IncrementAccessFailedCountAsync(user); 

     var shouldLockoutUser = accessFailedCount > MaxFailedAccessAttemptsBeforeLockout; 

     if (shouldLockoutUser) 
     { 
      await _userLockoutStore.SetLockoutEnabledAsync(user, true); 

      var lockoutEndDate = new DateTimeOffset(DateTime.Now + DefaultAccountLockoutTimeSpan); 

      await _userLockoutStore.SetLockoutEndDateAsync(user, lockoutEndDate); 
     } 
    } 
} 

[AllowAnonymous] 
    [HttpPost] 
    public async Task<ActionResult> Login(string userName, string password) 
    { 
     var userManager = new LockingUserManager<MyUser, int>(new MyUserStore()) 
     { 
      DefaultAccountLockoutTimeSpan = /* get from appSettings */, 
      MaxFailedAccessAttemptsBeforeLockout = /* get from appSettings */ 
     }; 

     var user = await userManager.FindAsync(userName, password); 

     if (user == null) 
     { 
      // bad username or password; take appropriate action 
     } 

     if (await _userManager.GetLockoutEnabledAsync(user.Id)) 
     { 
      // user is locked out; take appropriate action 
     } 

     // username and password are good 
     // mark user as authenticated and redirect to post-login landing page 
    } 

Source

+0

これについては混乱しているかもしれませんし、質問に対処できません。私がコードから取ったものは、ユーザーがログイン試行の失敗から来たロックアウト状態にあるかどうかを確認するために使用されます。これは、ログアウト時間とログイン試行失敗回数をロックする前に設定するように見えます。私はちょうどアカウントを無効にできるかどうかを調べています。 IsActive = falseを設定するようなことをする。そうすれば、彼らはちょうど期間にログインすることができません。更新が発生したら、IsActive = trueをリセットするだけです。それに似た何か。私はまだコードをさらに見て、それがうまくいくかどうかを見ます。 – Caverman

+0

私は、ユーザーを無効にするために実装しようとしているというアイデアを捨てたかったのです。私は "NoAccess"のような役割を作ります。私のコントローラーでは、ActionResultに到達できるような役割は含めません。私の場合は、誰かがサインアップするときに私をデフォルトの役割として使用します。それが私の必要を世話すると思います。 – Caverman

+0

しかし、特定のログイン失敗後にIdentityをロックアウトしないように設定するか、上記のコードを使用する必要があるようです。私はマイクロソフト社がロックアウトされている誰かを見ることや、ロック解除するためのより簡単な方法を見やすくしていないことに驚いています。 – Caverman

3

これについていくつかの調査を行いましたが、IdentityUserベースクラスには、このトピックに関連するいくつかのプロパティがあります。すなわち、LockoutEnabledLockoutEndDateUtcです。

それは、それをピックアップし、任意のオーバーライドまたはカスタマイズせずに応じて行動するために、標準SignInManager.PasswordSignInAsyncためには、いくつかの将来の日付にtrueLockoutEndDateUtcLockoutEnabledを設定するのに十分です。

再アクティブ化の正確な日付を指定せずにユーザーを無効にする場合は、DateTime.MaxValueに設定するだけです。

関連する問題