ASP.NET Identity のセキュリティスタンプ機能を使う
ASP.NET Identity に IUserSecurityStampStore
そもそも ASP.NET Identity って何?というのは CodeZine の ASP.NET Identity入門 が非常に分かりやすいです。
UserStore が実装するインタフェース
ASP.NET Identity には拡張を容易にするためにたくさんのインタフェースがあります。
そのインタフェースも、責務によって大きくいくつかのカテゴリに分けられるのですが、UserStore
- IUserLoginStore
- IUserClaimStore
- IUserRoleStore
- IUserPasswordStore
- IUserSecurityStampStore
- IUserStore
- IDisposable
全体的に名前だけで何となく想像がついたんですが、IUserSecurityStampStore<TUser>
だけが何なのか MSDN を見てもさっぱり分からず。。。
IUserSecurityStampStore の役割
stackoverflow に私と同じ疑問を持った方がいました。実装者に回答してもらっています。
What is ASP.NET Identity's IUserSecurityStampStore
あー、なるほどー。
どこからでも全てのログインセッションを無効化できるようにすることを目的とした、ログイン情報のスナップショットらしいです。 クッキーに、ログインに紐付くセキュリティスタンプとやらをを埋め込んでいるようですね。
例えば、ユーザがパスワードを変更したらその時点で即座に現在のログインセッション以外全てを無効にする用途に使うわけですね。あるあるー。
その仕組み、っていうより実現するために埋め込む情報のこと、セキュリティスタンプって言うらしいです。勉強になりました。
IUserSecurityStampStore の使い方
ではセキュリティスタンプを使っていきましょう。
といっても実は、Visual Studio 2013 Update3 で ASP.NET MVC Web アプリケーションを作った場合既定で有効になっています。
設定箇所は App_Start\Startup.Auth.cs
の以下のコードです。
public void ConfigureAuth(IAppBuilder app) { app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>( validateInterval: TimeSpan.FromMinutes(30), regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) } }); app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); }
上記コード中で、CookieAuthenticationProvider
クラスの OnValidateIdentity
プロパティに設定している SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>
メソッドがそうです。なので、もしセキュリティスタンプ機能が必要ない場合はここをコメントアウトすれば OK です。
動かしてみる
では実際に試して見ましょう。
初期設定では、セキュリティスタンプが変更されても、それを検証するまでに 30 分のタイムラグがあります。
なので、検証のために上記 SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>
メソッドの validateInterval
引数を変更します。
// OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>( // validateInterval: TimeSpan.FromMinutes(30), // regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>( validateInterval: TimeSpan.FromSecond(1), regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
これで即座に検証されるようになりました。
では、ソリューションをデバッグ実行して、Chrome でアクセスします。
↓の画像は、適当なユーザを作成してログインまで終わったところです。
次は IE で同じ事をやりましょう。
さて。ここで Chrome 側のセッションでパスワードを変更します。
そして、IE 側をリロードすると、、、
ログアウトされました!
ちなみに、パスワード変更じゃなくてログアウトしたらどうなるのっと試して見たら 普通にセッションが継続されました。だめじゃん!!
もしログアウトなど任意のタイミングでセキュリティスタンプを更新したいときは、 UserManager.UpdateSecurityStampAsync
メソッドを呼びましょう。
まとめ
まとめると、IUserSecurityStampStore<TUser>
インタフェースとはつまり、、、
- セキュリティスタンプの生成が責務
- この仕組みにより、任意のタイミングで自身以外のセッションを全て無効化できる
- が、セキュリティスタンプの検証は別のクラスが行う
- 細かい設定は OWIN の Configuration で
ということでした。よく出来てますね。