【図解あり】SSO・Kerberos認証・SAML・OIDC・OAuthの違いの理解不足に終止符を打つ

# はじめに

Webシステム関連の業務を遂行する上で、認証関連の用語(SSO, Kerberos認証, SAML, OIDC, OAuth)を目にする機会は多いですよね。
これらの用語の違いを言えますか？使い分けをできますか？な～んとなく理解してるけれど、口頭で説明しろと言われると難しい…という方も多いのではないでしょうか。
そう、私もその1人です...

そこで、自身の学習がてら備忘録としてまとめました。私と状況が似ている方、ご参考になれば幸いです。

# 結論

超端的に結論です。

**〇 SSO(Single Sign-On)**
**概念**です。
どんな概念？　一度の認証で複数サービスを横断的に利用できる概念です。
SSOの実現には様々な方法があります。それが1つ下の3つの認証です。

**〇 Kerberos認証, SAML, OIDC**
**認証プロトコル**です。SSOを実現するためのものです。
各違いについては、[詳細](#詳細)にまとめています。

**〇 OAuth2.0**
**認可プロトコル**です。
単体ではSSOを実現できないです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487776/87583cf8-c5c7-4620-a003-c081900dc456.png)

# 詳細

## 1. SSO(Single Sign-On)

### ■ SSOとは
SSOは、**一度の認証で複数のサービスを利用できるようにする概念**です。
例としては、Googleアカウントでログインをすると、Gmail, Google Drive, YouTubeなど、Googleの複数のサービスにログインできるようになりますよね、あれです。
↑おおよそSSOのイメージは掴めていると思うので、ここではメリットだけ触れてKerberos認証, SAML, OIDCの詳細に移りたい思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487776/8bccb10d-84c6-4597-895a-cb48b07aa264.png)

### ■ メリット

**〇 ユーザビリティの向上**
これは誰でもわかりますよね。一回のログインで複数のサービスを利用できるので、ユーザは毎回ログインする手間が省けます。

**〇 セキュリティの向上**
パスワードの管理が一元化、セキュリティポリシーを統一できるため、セキュリティが向上します。認証情報がトークンとして扱われるため、漏洩リスクも低減します。

**〇 運用の効率化**
運用側も、ユーザ管理や認証情報の管理が一元化されるため、運用コストが削減されます。

## 2. Kerberos認証

### ■ Kerberos認証とは
Kerberos認証は、SSOを実現するための**認証プロトコル**の一つです。
他の認証との違いとしては**チケットベースの認証方式**です。
例としては、遊園地を想像をしてもらえると分かりやすいと思います。入場チケットを元に、アトラクションチケットを受け取るイメージです。
詳細は[■ 認証フロー](#-認証フロー)に記載しているので、見てみてください。

### ■ 特徴

**〇 チケットベースの認証**
ユーザは一度ログインすると、チケットを受け取ります。このチケットを使って、他のサービスにアクセスできます。
チケットはHTTPリクエストのヘッダーで送付します。

**〇 主に社内システムで利用**
WindowsのActive Directoryなどに、Kerberos認証の機能があるため、社内ネットワークで利用されることが多いです。

### ■ 登場人物

暗記する必要はありませんが、理解しておくと認証フローが分かりやすくなると思います。

- **KDC（Key Distribution Center）**: Kerberos認証の中心となるサーバ。認証&チケットの配布を行う。KDCは以下で構成。
  - **AS（Authentication Server）**: 認証サーバ。ユーザ認証&配布用チケット（TGT: Ticket Granting Ticket）を発行。
  - **TGS（Ticket Granting Server）**: チケット付与サーバ。配布用チケットを確認&サーバーアクセス用チケット（ST: Service Ticket）を発行。

- **TGT（Ticket Granting Ticket）**: 配布用チケット。ASにて発行。TGSにてSTを取得するために使用される。
- **ST（Service Ticket）**: サーバーアクセス用チケット。TGSにて発行。これにより、目的のサービスにアクセスできる。

### ■ 認証フロー

Kerberos認証のフローです。
今回は他の認証との違いに重点を置いているため、タイムスタンプや暗号化の詳細は省略します。
フロー②で取得した**配布用チケット**（TGT）は、使いまわしが出来るため、これによりSSOが実現します。

①ユーザは**認証サーバ**(AS)に**IDとパスワード**を送信。  
②**認証サーバ**(AS)は**IDとパスワード**の検証が成功すると、**配布用チケット**（TGT）を発行。  
-------------ここまで①②が遊園地の入場チケットを受け取る段階になります。  
③ユーザは**チケット付与サーバ**(TGS)に**配布用チケット**を送信。  
④③の検証が成功すると、**サーバーアクセス用チケット**（ST: Service Ticket）を発行。  
-------------ここまで③④が入場チケットをもとに遊園地のアトラクションチケットを受け取る段階になります。  
⑤ユーザは**サーバーアクセス用チケット**（ST）を使って、目的のサービスにアクセス。  
⑥サーバは**サーバーアクセス用チケット**（ST）の検証&サービス提供。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487776/ab7935b3-324e-470f-9918-25faf9c4b28f.png)

## 3. SAML(Security Assertion Markup Language)

### ■ SAMLとは
こちらもSSOを実現するための**認証プロトコル**の一つです。
他の認証との違いとしては**XMLベースの標準であること**です。
XMLベースの標準であること..?と思われる方もいるかもしれません。これは、SAMLがXML形式で認証情報を格納し、送信するプロトコルのことです。

### ■ 特徴

**〇 XMLベースの標準**
SAMLはXMLベースの標準で、認証情報をセキュアに交換するためのプロトコルです。
XML形式の認証情報は、リダイレクトURLのクエリパラメータやHTTP POSTリクエストのボディで送付されます。

**〇 IDプロバイダとサービスプロバイダ**
SAMLでは、IDプロバイダ（IdP）とサービスプロバイダ（SP）が存在します。IdPは認証を行い、SPはサービスを提供します。

### ■ 登場人物

暗記する必要はありませんが、理解しておくと認証フローが分かりやすくなると思います。

- **IdP（Identity Provider）**: 認証サーバ。
- **SP（Service Provider）**: サービスプロバイダ。サービスを提供するサーバ。
- **アサーション（Assertion）**: 認証情報を含むXMLドキュメント。IdPがSPに送信。

### ■ 認証フロー

SAMLのフローです。

①ユーザは**サービスプロバイダ**(SP)にアクセス。  
②ログイン済みセッションがないことを検知し、**サービスプロバイダ**(SP)は、**認証サーバ**(IdP)へのリダイレクトレスポンスと認証依頼情報(XML)をユーザへ返却。  
③ユーザはリダイレクトに従って認証依頼情報(XML)を含み**認証サーバ**(IdP)へリクエスト。  
④**認証サーバ**(IdP)は、認証依頼情報(XML)を検証して、ユーザ認証用のログイン画面をユーザへ返却。  
⑤ユーザは**認証サーバ**(IdP)に**ID&パスワード**を送信。  
⑥**認証サーバ**(IdP)は**ID&パスワード**の検証＆サーバ(SP)へのリダイレクトレスポンスと認証情報(XML)をユーザへ返却。  
⑦ユーザはリダイレクトに従って認証情報(XML)を含み**サービスプロバイダ**(SP)へリクエスト。  
⑧**サービスプロバイダ**(SP)は認証情報(XML)の検証が成功すると、ユーザにサービスを提供。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487776/e40c15bf-2a13-4cc6-b631-60ffbd4bb52f.png)

## 4. OAuth2.0

OIDCについて触れたいところですが、先にOAuth2.0についてまとめさせてください。
というのも、OIDCはOAuth2.0の拡張仕様であり、OAuth2.0を先に理解した方がOIDCの理解が深まるからです。

### ■ OAuth2.0とは

OAuth2.0は、**認可（Authorization）**を行うためのプロトコルです。
ユーザーの「**本人確認（認証）**」ではなく、
「**特定のクライアントに対し、限定的にアクセス権を与える**」ために利用されます。

> 認証が必要な場合は、OAuth2.0の拡張仕様である**OIDC（OpenID Connect）**を使います。

### ■ 登場人物

暗記する必要はありませんが、理解しておくと認証フローが分かりやすくなると思います。

- **リソースオーナー（Resource Owner）**: ユーザ本人。
- **クライアント（Client）**: 保護されたリソースにアクセスするアプリケーションやサービス。例：Webアプリケーション、API、モバイルアプリ。
- **認可サーバ（Authorization Server）**: リソースオーナーの認可&アクセストークンを発行するサーバ。
- **リソースサーバ（Resource Server）**: 保護されたリソースを提供するサーバ。クライアントからのアクセストークン検証し、アクセスを許可する。
- **アクセストークン（Access Token）**: クライアントがリソースサーバにアクセスするためのトークン。認可サーバから発行される。

### ■ 認可フロー

OAuth2.0にはいくつかのフローがあります。
- **Authorization codeフロー**
- **Client Credentials フロー**
- **Implicit フロー**
- **Resource Owner Password Credentials フロー**
- **Refresh Token フロー**

今回は一般的に利用される**Authorization codeフロー**をまとめます。

①リソースオーナーが**クライアント**にアクセス。  
②**クライアント**はリダイレクトレスポンスと認可依頼情報をリソースオーナーへ返却。  
③リソースオーナーはリダイレクトに従って認可依頼情報を**認可サーバ**へリクエストします。  
④**認可サーバ**は、認可依頼情報の検証&リソースオーナーへ認可用のログイン画面を返却。  
⑤リソースオーナーは**認可サーバ**に**IDとパスワード**を送信。  
⑥**認可サーバ**はIDとパスワードの検証&**クライアント**へリダイレクトレスポンスと認可コードをリソースオーナーへ返却。  
⑦リソースオーナーはリダイレクトに従っての認可コードを含み**クライアント**へリクエスト。  
⑧**クライアント**は、**認可サーバ**にアクセストークン取得のため、認可コードを含みリクエスト。  
⑨**認可サーバ**は、認可コードの検証&アクセストークンを発行し、**クライアント**へ返却。  
⑩**クライアント**は、アクセストークンを使って保護された**リソースサーバ**へリクエスト。  
⑪リソースサーバはアクセストークンの検証&保護されたリソースを**クライアント**へ返却。  
⑫**クライアント**は、保護されたリソースをリソースオーナーへ返却。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487776/ce3689f1-44d0-4ae3-b9d9-d7b56b9474cc.png)

その他フローは以下の記事が分かりやすく、参考になりました。

https://qiita.com/hka9/items/09ba27108a68760f0842

## 5. OIDC（OpenID Connect）

### ■ OIDCとは？

OIDC（OpenID Connect）は、**OAuth2.0をベースに拡張された認証プロトコル**です。
OAuth2.0が「認可（何ができるか）」を扱うのに対し、OIDCは「**認証（誰であるか）**」を扱います。

> つまり、OAuth2.0では「本人確認」はできません。
> OIDCは、それを補うために作られた\*\*"OAuth2.0に認証を追加する仕組み"\*\*です。

### ■ OIDCの特徴

**〇 認可＋認証**
OAuth2.0でアクセストークンを取得しつつ、IDトークンでユーザーの「本人確認」ができます。

**〇 IDトークン**
ユーザーの認証情報を含むトークン。JWT形式(JSON Web Token)で署名付きで提供されます。
JWT形式はJSONで表現された認証情報を安全に送受信するための標準規格になります。

**〇 標準エンドポイント**
`/authorize`, `/token`, `/userinfo` などが定義されているため、クライアントはこれらのエンドポイントを利用して認証を行えるため、実装が容易になります。

JWT形式については、以下の記事が参考になりました。

https://qiita.com/t-toyota/items/8d0ffb265845ab8cc87c

### ■ OIDCの登場人物
暗記する必要はありませんが、理解しておくと認証フローが分かりやすくなると思います。
- **リソースオーナー（Resource Owner）**: ユーザ本人。
- **クライアント（Client）**: 保護されたリソースにアクセスするアプリケーションやサービス。例：Webアプリケーション、API、モバイルアプリ。
- **認可サーバ（Authorization Server）**: リソースオーナーの認可&アクセストークンを発行するサーバ。
- **リソースサーバ（Resource Server）**: 保護されたリソースを提供するサーバ。クライアントからのアクセストークン検証し、アクセスを許可する。
- **アクセストークン（Access Token）**: クライアントがリソースサーバにアクセスするためのトークン。認可サーバから発行される。
- **IDトークン（ID Token）**: ユーザの認証情報を含むトークン。JWT形式で提供される。

### ■ OAuth2.0との違い（まとめ）

| 項目       | OAuth2.0     | OIDC                        |
| -------- | ------------ | --------------------------- |
| 主目的      | 認可           | 認証＋認可                       |
| トークン     | アクセストークン     | アクセストークン＋IDトークン             |
| ユーザー情報取得 | APIアクセスで別途取得 | IDトークン or `/userinfo` で取得可能 |
| フロー      | 認可コードフローなど   | OAuth2.0と同じ＋IDトークン取得が追加される  |
| SSO対応    | 非対応          | 対応（トークンベースで可能）              |

### ■ 認証フロー

認証フローですが、情報の流れとしてはOAuth2.0の認可コードフローと同じです。
プラスで認証のためのIDトークンが取得される点が異なります。

①ユーザーが**クライアント**にアクセス。  
②**クライアント**はリダイレクトレスポンスをユーザへ返却。  
③ユーザは②の認証依頼情報を元に**認可サーバ**(Authorization Server)へリクエスト。  
④**認可サーバ**(Authorization Server)は、認証依頼情報を検証して、ユーザ認証用のログイン画面を返却。  
⑤ユーザは**認可サーバ**(Authorization Server)に**IDとパスワード**を送信。  
⑥⑤の検証が成功すると、**認可サーバ**(Authorization Server)は、**クライアント**(Client)へのリダイレクトレスポンスを認可コード`+OIDC認証リクエストパラメータ`を含みユーザへ返却。  
⑦ユーザはブラウザのリダイレクトに従って認可コード`+OIDC認証リクエストパラメータ`含むリクエストをクライアントに送信。  
⑧⑦の検証が成功すると、**クライアント**(Client)は、**認可サーバ**(Authorization Server)にアクセストークン`+IDトークン`をリクエスト。  
  　＋ 認可コード`+OIDC認証リクエストパラメータ`を送信。  
⑨**認可サーバ**(Authorization Server)は、アクセストークン`+IDトークン`を発行し、**クライアント**(Client)に返却。  
⑩**クライアント**(Client)は、IDトークンを検証&アクセストークンを使って保護されたリソースサーバへリクエスト。  
⑪⑩の検証が成功するとリソースサーバは、保護されたリソースを*クライアント*へ返却。  
⑫**クライアント**(Client)は、保護されたリソースをユーザへ返却。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487776/a89dfc0c-dcd7-4eb9-bbc8-a11e5df203d7.png)

# 最後に
以上になります。呼んでいただいた方、ありがとうございました。
もし、間違いや補足情報があれば、コメントお願いします。

# 参考資料

https://datatracker.ietf.org/doc/html/rfc4120

https://datatracker.ietf.org/doc/html/rfc6749

https://qiita.com/mkt_hanada/items/3b9e5a9b343674f2fa40

https://qiita.com/ykna/items/2367fe3cd13460baac9f

https://zenn.dev/osachi/articles/aff5105d39d877

https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be

https://zenn.dev/crebo_tech/articles/article-0011-20241006

https://zenn.dev/bonvoyage/articles/5dda6a1effd022