ASP.NET Core MVCのセッションタイムアウトと認証タイムアウト

ASP.NET Core 2.1～5.0までは同じみたい。
実際にプログラムで確認したのはASP.NET Core 3.1です。

#認証タイムアウト
ASP.NET Core MVCでCookieによる認証の利用及びタイムアウトの設定
###１．Startup.csのConfigureServicesに認証サービスを登録する

```C#:Startup.cs
//CookieAuthenticationDefaults.AuthenticationSchemeのスキーム名は別の文字に変更することも可能
//例えば：MyLoginScheme
//だが変更され場合は利用する際はスキーム名を変更されたスキーム名と一致する必要があります。
//.AddCookieでは認証用のCookieに関する設定です
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
	.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, option =>
	 {
         //AuthenticationSchemeという認証スキームの共通設定

         //HttpContext.ChallengeAsync(認証チャレンジ)で認証失敗した場合のリダイレクト先
         //簡単に言うとログインされていない時にログインが必要の機能へアクセスする時のリダイレクト先
	     option.LoginPath = "/LoginController/LoginAction";
         //HttpContext.ForbidAsync（認証されているが、必要な権限がない時の禁止）でのリダイレクト先
         //ログインされている、だがアクセスする機能に必要な権限が足りない時のリダイレクト先
	     option.AccessDeniedPath = "/LoginController/ForbidAction";
         
         //該当スキームのCookie名、デフォルトは.AspNetCore.Cookies
	     option.Cookie.Name = "token";
         //Cookieの中に保存されている認証データの有効期限、ここでは5分以内にサーバーへアクセスがないと認証タイムアウトが発生する
	     option.ExpireTimeSpan = TimeSpan.FromMinutes(5);
         //その他の設定に関しては省略する
	 });
```

**①認証Cookieのタイムアウト設定**

```C#:
option.ExpireTimeSpan = TimeSpan.FromMinutes(5);
```

認証と禁止の詳細については下記を参照

* [ASP.NET Core の認証の概要](https://docs.microsoft.com/ja-jp/aspnet/core/security/authentication/?view=aspnetcore-5.0)
* [ASP.NET Core でのリソースベースの承認](https://docs.microsoft.com/ja-jp/aspnet/core/security/authorization/resourcebased?view=aspnetcore-5.0#challenge-and-forbid-with-an-operational-resource-handler)
* [認証によって保護されたユーザーデータを使用して ASP.NET Core web アプリを作成する](https://docs.microsoft.com/ja-jp/aspnet/core/security/authorization/secure-data?view=aspnetcore-5.0#challenge)

###２．Startup.csのConfigureに認証と認可ミドルウェアを登録する

```C#:Startup.cs
app.UseAuthentication();
app.UseAuthorization();
```

認証ミドルウェアの登録順番には要注意[登録順番はここから参照](https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0)

###３．実際の認証処理
例えば「LoginController」に「Login」という認証用アクションがあります

```C#:LoginController.cs
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> Login(string loginId,string loginPW,string ReturnUrl)
{
    //ログインID,パスワードチェック処理省略、ログイン出来ると仮定する
    var claims = new List<Claim>(){
                        new Claim(ClaimTypes.Sid,loginId)
                    };
    var identity = new ClaimsIdentity(claims, authSchema);
    var identityPrincipal = new ClaimsPrincipal(identity);
    
    //認証サービス登録する際に設定したスキームと同じものを設定
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, identityPrincipal, 
    	new AuthenticationProperties
            {
                //サーバーアクセスによる認証時間を更新する
                AllowRefresh = true,
                //認証の有効期間,認証cookieタイムアウト
                ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(5),
                //cookieの有効期間を優先かsessionを優先か
                //true:cookieが有効であれば、ブラウザを閉じても再ログインが必要ない
                //false:ブラウザ閉じたら再ログインが必要
                IsPersistent = false,
                //cookieの認証時間
                IssuedUtc = DateTime.UtcNow
            });
            
    return Redirect(ReturnUrl);
}

```

**②認証Cookieのタイムアウト設定**
②の設定が①より優先される

```C#:
ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(5)
```

#セッションタイムアウト
ASP.NET Core MVCでSessionの利用及びタイムアウトの設定

###１．Startup.csのConfigureServicesにセッションサービスを登録する

```C#:Startup.cs

services.AddSession(option=>
	{
	    //セッションタイムアウト、5分以上操作がないと
	    //デフォルトタイムアウトは20分
	    option.IdleTimeout = TimeSpan.FromMinutes(5);

	    //option.Cookieに関する設定はセッションのクライアントCookieに当たる
	    //認証Cookieとは別物です。デフォルトCookie名は「.AspNetCore.Session」
	});

```

###２．Startup.csのConfigureにセッションミドルウェアを登録する

```C#:Startup.cs
app.UseSession();
```

認証ミドルウェアの登録順番には要注意[登録順番はここから参照](https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0)


#結論

認証Cookieとセッションデータは違う物、セッションが取れない場合を認証されていないと同じ扱いにする際は両方のタイムアウトを必ず同じ設定する必要がある。

#####１．Cookieによる認証とセッション両方とも起用する際の注意
* 認証Cookieのタイムアウトとセッションタイムアウトの時間を同じにするのがお勧め
* 認証Cookieのタイムアウトが長い場合、セッションが切れた際のセッションデータの再構築が必要

#####２．認証する際に設定されたクレームセットの取得
* 認証データは直接HttpContext.Userに設定されています
* HttpContext.User.Identity.IsAuthenticatedで認証済みかを判断できる
* HttpContext.User.Claimsからはクレーム情報を取得できる