OAuth2.0について

## OAuth2.0とは
OAuth 2.0（Open Authorization 2.0）: Web サービスやアプリケーションの認可や認証を行うためのプロトコル。

OAuth を用いることで、ユーザーは自身のユーザーID/パスワードを使う代わりに、アクセストークンを使用してサードパーティーアプリケーションのデータにアクセスすることができます。こうすることで、ユーザーは自身のクレデンシャルをサードパーティーと共有することによるセキュリティリスクを抱えずに済むようになります。

### OAuth 2.0 の主要な概念と役割

- **リソースオーナー**（Resource Owner）: 通常、ユーザーのことを指します。

- **クライアント**（Client）: リソースオーナーの代理としてアクセストークンを取得しリソースサーバーへのアクセスを行います。ウェブアプリケーション、モバイルアプリケーション、デスクトップアプリケーション、API サービスなどを指します。

- **認可サーバー**（Authorization Server）:
認可サーバーは、クライアントがアクセストークンを取得するための認可プロセスを処理します。リソースオーナーの承認を受け、アクセストークンを発行します。IdP(Identity Provider)の役割を果たします。


- **リソースサーバー**（Resource Server）:
リソースサーバーは、保護されたリソースをユーザーに提供し、アクセストークンを使用してリクエストを検証します。SP（Service Provider）の役割を果たします。

### OAuth2.0のプロトコルフロー

```mermaid
sequenceDiagram
    participant ResourceOwner as リソースオーナー
    participant Client as クライアント
    participant AuthorizationServer as 認可サーバー
    participant ResourceServer as リソースサーバー

    Client->>ResourceOwner: 認可要求
    ResourceOwner->>Client: 認可グラントの付与
    Client->>AuthorizationServer: 認可グラントのリダイレクト
    AuthorizationServer->>Client: アクセストークンを返す
    Client->>ResourceServer: アクセストークンを使用したリソースへのアクセスリクエスト
    ResourceServer->>Client: リソースを返す
```

## 認可フローの種類について
- OAuth（Open Authorization）にはいくつかの異なる認可フローがあります。以下に、主要な OAuth 認可フローの種類を説明します
### Authorization Code フロー
- このフローは、Web アプリケーションやモバイルアプリケーションなどのクライアントがリソースオーナー（ユーザー）の承認を受け、アクセストークンを取得するための最も一般的な方法です。
- クライアントは、認可サーバーにリダイレクトされ、ユーザーに認証を要求します。ユーザーが認可を許可すると、認可コードがクライアントに返されます。その後、クライアントはこの認可コードを使用して認可サーバのトークンエンドポイントにアクセスし、アクセストークンを取得します。

```mermaid
sequenceDiagram
    participant User
    participant Client
    participant Authorization Server
    participant Resource Server
    
    User->>+Client: クライアントにアクセスを要求
    Client->>+Authorization Server: 認可リクエスト（Authorization Code リクエスト）
    Authorization Server-->>-Client: 認可コードを返す
    Client->>User: リダイレクト URI に認可コードを含む URL を返す
    User->>+Authorization Server: 認可コードを使用して認可を許可
    Authorization Server-->>-User: 認可済みリダイレクト URI にリダイレクト
    User->>+Client: 認可済みリダイレクト URI にリダイレクト
    Client->>+Authorization Server: アクセストークンリクエスト（Authorization Code レスポンス）
    Authorization Server-->>-Client: アクセストークンを返す
    Client->>+Resource Server: アクセストークンを使用してリソースリクエスト
    Resource Server-->>-Client: リソースを返す
```

### Client Credentials フロー
- このフローは、信頼されたクライアント（たとえば、サーバー上で実行されるバッチジョブや API サービス）が自身の名義で API にアクセスする場合に使用されます。
- クライアントがクレデンシャル（クライアント ID とシークレット）を使用して認可サーバのトークンエンドポイントに直接リクエストを送信し、アクセストークンを取得します。
```mermaid
sequenceDiagram
    participant Client
    participant Authorization Server
    participant Resource Server
    
    Client->>+Authorization Server: クライアント資格情報を使用したトークンリクエスト（Client Credentials リクエスト）
    Note over Authorization Server: 要クライアント認証
    Authorization Server-->>-Client: アクセストークンを返す
    Client->>+Resource Server: アクセストークンを使用してリソースリクエスト
    Resource Server-->>-Client: リソースを返す

```
### Implicit フロー(非推奨)
- このフローは、JavaScript を使用してクライアント側で実行されるアプリケーション（たとえば、SPA）や、モバイルアプリケーションなどの場合に使用されます。
- クライアントがユーザーの認可を取得し、リダイレクト URI にアクセストークンを含むフラグメントを返すように要求します。このフローでは、認可コードは使用されません。
- トークン漏洩リスクが高いため、現在非推奨とされています。(参照：https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-15#section-appendix.a-7.1.1)
```mermaid
sequenceDiagram
    participant User
    participant Client
    participant AuthorizationServer
    participant ResourceServer

    User->>Client: リソースにアクセスを要求
    Client->>AuthorizationServer: アクセストークンの取得リクエスト
    AuthorizationServer->>Client: アクセストークンを返す
    Client->>ResourceServer: アクセストークンを使用したリソースへのアクセスリクエスト
    ResourceServer->>Client: リソースを返す

```

### Resource Owner Password Credentials フロー(非推奨)

- このフローは、信頼されたクライアントがユーザー名とパスワードを使用してアクセストークンを取得する場合に使用されます。
- クライアントがユーザーの資格情報を使用して直接トークンエンドポイントにリクエストを送信し、アクセストークンを取得します。このフローに関してもImplicit フロー同様トークン漏洩リスクが高く、現在非推奨とされています。(参照：https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-15#section-appendix.a-7.1.1)
```mermaid
sequenceDiagram
    participant User
    participant Client
    participant Authorization Server
    participant Resource Server
    
    User->>+Client: ユーザー名とパスワードを提供
    Client->>+Authorization Server: ユーザー名とパスワードを使用したトークンリクエスト（Resource Owner Password Credentials リクエスト）
    Authorization Server-->>-Client: アクセストークンを返す
    Client->>+Resource Server: アクセストークンを使用してリソースリクエスト
    Resource Server-->>-Client: リソースを返す
```

### Refresh Token フロー
- アクセストークンの有効期限切れの場合は、事前に発行を受けていたリフレッシュトークンを認可サーバのトークンエンドポイントに提示することにより、アクセストークンの再発行を受けます。
```mermaid
sequenceDiagram
    participant Client
    participant Authorization Server
    participant Resource Server

    Client->>+Authorization Server: リフレッシュトークンを使用したトークンリクエスト
    Authorization Server-->>-Client: 新しいアクセストークンを返す
    Client->>+Resource Server: 新しいアクセストークンを使用したリソースリクエスト
    Resource Server-->>-Client: リソースを返す
```

## Client Typesについて
- クライアントアプリケーションにはクライアントタイプというものがあり、publicもしくは confidentialのどちらかです。

- https://openid-foundation-japan.github.io/rfc6749.ja.html#client-types によると、次のように定義されています。
  - **コンフィデンシャル** (confidential)
    - クレデンシャルの機密性を維持することができるクライアント (例えば, クライアントクレデンシャルへのアクセスが制限されたセキュアサーバー上に実装されたクライアント), または他の手段を使用したセキュアなクライアント認証ができるクライアント.
  - **パブリック** (public)
    - (例えば, インストールされたネイティブアプリケーションやブラウザベースのWebアプリケーションなど, リソースオーナーのデバイス上で実行されるクライアントのように) クライアントクレデンシャルの機密性を維持することができず, かつ他の手段を使用したセキュアなクライアント認証もできないクライアント.

#### Public Clientを用いる時の注意点

- Public Client の場合は認可リクエスト/レスポンスだけでなくクライアントと認可サーバー/リソースサーバー間の通信内容(下図の①,②の部分)も第3者に知られる可能性があるので、Access Tokenの有効期限を短くしたりRefresh Tokenを発行しないなどの考慮をする必要があります。
```mermaid
sequenceDiagram
    participant User
    participant Client
    participant Authorization Server
    participant Resource Server
    
    User->>+Client: クライアントにアクセスを要求
    Client->>+Authorization Server: 認可リクエスト（Authorization Code リクエスト）
    Authorization Server-->>-Client: 認可コードを返す
    Client->>User: リダイレクト URI に認可コードを含む URL を返す
    User->>+Authorization Server: 認可コードを使用して認可を許可
    Authorization Server-->>-User: 認可済みリダイレクト URI にリダイレクト
    User->>+Client: 認可済みリダイレクト URI にリダイレクト
    opt  Public Clientの場合この部分で情報漏洩のリスクがある
    Client->>+Authorization Server: ①アクセストークンリクエスト（Authorization Code レスポンス）
    Authorization Server-->>-Client: アクセストークンを返す
    Client->>+Resource Server: ②アクセストークンを使用してリソースリクエスト
    Resource Server-->>-Client: リソースを返す
    end
    Client-->>-User: リソースを返す
```
- もしくは、クライアントにBackend Serverがある場合は、認可サーバー/リソースサーバーとのやりとりを Backend Server に任せることにより、Backend Serverがconfidentialなクライアントとなるので、全体で見てセキュアな実装とすることができます。
```mermaid
sequenceDiagram
    participant User
    participant Client        
    participant Client Backend
    participant Authorization Server
    participant Resource Server
    
    User->>+Client: クライアントにアクセスを要求
    Client->>+Authorization Server: 認可リクエスト（Authorization Code リクエスト）
    Authorization Server-->>-Client: 認可コードを返す
    Client->>User: リダイレクト URI に認可コードを含む URL を返す
    User->>+Authorization Server: 認可コードを使用して認可を許可
    Authorization Server-->>-User: 認可済みリダイレクト URI にリダイレクト
    User->>+Client: 認可済みリダイレクト URI にリダイレクト
    Client->>+Client Backend: 認可済みリダイレクト URI にリダイレクト
    Client Backend->>+Authorization Server: ①アクセストークンリクエスト（Authorization Code レスポンス）
    Authorization Server-->>-Client Backend: アクセストークンを返す
    Client Backend->>+Resource Server: ②アクセストークンを使用してリソースリクエスト
    Resource Server-->>-Client Backend: リソースを返す
    Client Backend-->>-Client: リソースを返す
    Client-->>-User: リソースを返す
```
- 上記の内容は、以下の記事に詳しく説明してありました。
  - https://zenn.dev/ritou/articles/d26c7861047a2d


## まとめ
今回は以下の内容についてまとめてみました。
- OAuth2.0の概要
- 認可フローのパターンについて
- Client Typeについて、またそれに関するセキュリティリスクについて

概念の理解はできたので、いつか認証の実装もしてみたいです。