ASP.NET Core の認証周りのメモ

# .NET Core の認証周りのメモ
認証周りのところを少し読んでみたので備忘メモ

調べたバージョンはASP.NET Core 3.1 

結論を先に書くと`IAuthenticationHandler` が一つのポイントとなっているようだ

## 登場するクラスメモ

### AuthenticationMiddleware
[ソース](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Security/Authentication/Core/src/AuthenticationMiddleware.cs)


`Startup.cs` で`app.UseAuthentication();` を実行することで有効化される。

前半部分の処理は不明ですが、
cookieなどから認証情報をとりだし `HttpContext.User` にセットしているようです。

試しに `app.UseAuthentication();` をコメントアウトしたところ、認証情報が取得できず`[Authorize]` をつけているところははじかれる

### AuthorizationMiddleware
[ソース](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs)

`Startup.cs` で`app.UseAuthorization();` を実行することで有効化される。
前述の`app.UseAuthentication();` の結果を利用するのでその後に呼び出す必要がある。

`[Authorize]` 属性をつけているとここで 認可の処理が実行されるようだ。
(`[Authorize]` 属性はフィルターではないが `IAuthorizeData` を実装している)
`[AllowAnonymous]` が付与されていると次で述べるチェックが行われないような感じ。

認可のチェックは`IPolicyEvaluator` によって実行される。
この結果によって、チャレンジが必要なら`HttpContext.ChallengeAsync` を実行し、禁止されているなら`HttpContext.ForbidAsync` を呼んでいるようである。

### IPolicyEvaluator
ここでは実装クラス[PolicyEvaluator](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Security/Authorization/Policy/src/PolicyEvaluator.cs) のメモを書く

`AuthorizationMiddleware` で呼ばれた `AuthorizeAsync` メソッドでは `IAuthorizationService.AuthorizeAsync` に処理を委譲し、その結果によって「成功」「チャレンジが必要(ログイン画面へのリダイレクトなど)」「禁止」などの結果を返している

### IAuthorizationService
ここでは実装クラス[DefaultAuthorizationService](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Security/Authorization/Core/src/DefaultAuthorizationService.cs) のメモを書く

`IAuthorizationHandler` あたりに認可の処理を委譲してる感じかな？(わかんね)

そしてその結果を返している。

### AuthenticationHttpContextExtensions
[ソース](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Http/Authentication.Abstractions/src/AuthenticationHttpContextExtensions.cs)

上記のミドルウェアなどから`HttpContext` のメソッドを呼び出しているが、これらは拡張メソッドとして定義されており、DIコンテナから取得したインスタンスに処理を委譲しているだけのようだ。

オーバーロードがされているが、整理すると以下のものになる。

- AuthenticateAsync
- ChallengeAsync
- ForbidAsync
- SignInAsync
- SignOutAsync
- GetTokenAsync

これらのメソッドはいずれもコンテナから `IAuthenticationService` を取得し、同名のメソッドを実行している。

### IAuthenticationService
ここでは実装クラス[AuthenticationService](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Http/Authentication.Core/src/AuthenticationService.cs) のメモを書く

いずれも差はあれど

- スキーマ名が渡されていなければ、`IAuthenticationSchemeProvider` から対象のスキーマ名を取得
- `IAuthenticationHandlerProvider` からスキーマ名に対応した `IAuthenticationHandler` を取得
- 取得した`IAuthenticationHandler` に処理を委譲

となっている。
`SignInAsync`, `SignOutAsync` は選ばれたハンドラーがそれぞれに対応したインターフェースを実装している必要があるようだ。

### IAuthenticationHandler
認証関係の処理の到達先がここになっている。

これは認証方法によって様々な実装クラスが用意されている。

`Cookie` 認証の場合だと [CookieAuthenticationHandler](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs)になる

## DIコンテナに関連するクラスを登録する方法

### 認証関係
認証に関連するものは`Startup.cs`で
`services.AddAuthentication()` を実行すればよい
呼び出し先は[AuthenticationServiceCollectionExtensions](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Security/Authentication/Core/src/AuthenticationServiceCollectionExtensions.cs)

この中でも`services.AddAuthenticationCore()` メソッド
呼び出し先は[AuthenticationCoreServiceCollectionExtensions](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Http/Authentication.Core/src/AuthenticationCoreServiceCollectionExtensions.cs)

で認証に関連するクラスが登録されている。

個別の認証を定義するには

```cs
services.AddAuthentication(option =>
{
    option.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
;
```
のように`AddAuthentication` に続けて書く

`.NET Identity` でも[IdentityServiceCollectionExtensions](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Identity/Core/src/IdentityServiceCollectionExtensions.cs) の中で上記の事が行われており、さらに追加のクラスが登録されているようです。

### 認可関係

認可に関連するものは`Startup.cs` で`service.AddMvc()`, `service.AddControllers()`, `services.AddControllersWithViews()` などを実行すれば登録される。
これは[MvcServiceCollectionExtensions](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Mvc/Mvc/src/MvcServiceCollectionExtensions.cs#L147) で`AddAuthorization` が実行されているためである。

`AddAuthorization` は[PolicyServiceCollectionExtensions](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Security/Authorization/Policy/src/PolicyServiceCollectionExtensions.cs)で定義されており
この中で呼びだしている `services.AddAuthorizationCore`が登録を行っている

`AddAuthorizationCore` は[AuthorizationServiceCollectionExtensions](https://github.com/dotnet/aspnetcore/blob/v3.1.4/src/Security/Authorization/Core/src/AuthorizationServiceCollectionExtensions.cs)で定義されており、ここで認証に関連するクラスが登録されている。

## おわりに
ひとまず登場するクラス群とその流れについてメモを残しました。