認証と認可の違いに関して勉強した事を書き連ねてみる。

# 背景

以前、[認証に関する記事](https://qiita.com/etnk/items/1c5579db53ddecf3a74d)を書かせてもらいました。その中で、以下の様に次の目標を書きました。
> 実際にSAMLを使用してログイン処理や機能認可を実装してみる事で理解を深めていきたい所です。

が、そんな中色々思う所があり、その前にモヤッとしている事をハッキリさせておこうと思いました。
既にタイトルに書いていますが、認可と認証の違いに関してです。

# 基本知識を仕入れる

## 言葉的な意味を把握してみる

`認証認可`でググると、保育所の話が多く出てきます。以下のサイトが参考になりました。

[認可保育所と認証保育所の違い](https://www.fukunavi.or.jp/fukunavi/contents/tokushu/ninsyo/ninsyo_02.html)

認可保育所は、国が`許可`した（補助を受ける権限を得た）保育所。認証保育所は都が特定の基準を満たしていると`確認して保証（？）`した（基準を満たすと確認した）保育所。という事の様です。間違ってたら指摘お願いします。認可外保育所というのもありますね。

## 具体的な世の中の事柄で把握してみる

言葉の意味を踏まえた所で、本題であるコンピューターシステムにおける認証と認可の知識を仕入れたいと思います。以下のサイトが非常に参考になりました。

[よくわかる認証と認可](https://dev.classmethod.jp/articles/authentication-and-authorization/)

Classmethodさんのの記事ではありますが、技術的な話中心ではなく、世の中の具体的な事柄と認証認可を結び付けて解りやすく説明しています。

[認証に基づく認可](https://dev.classmethod.jp/articles/authentication-and-authorization/#toc-10)、[認可に基づく認証（！？）](https://dev.classmethod.jp/articles/authentication-and-authorization/#toc-11)の二つが今回の自分の目的的には重要に思いました。

ちょっと話がずれますが、これらの部分を読んでAWSの資格試験で２種類の証明書（写真付きの政府発行の本人証明書と、名前とサイン入りの本人証明書）が必要な事が納得できした。本人である事を証明するものと、本人以外が持つ事がほぼ無い（クレジットカードとか）もので認証的な確認と認可的な確認を両方してるわけですね（ちょっと違うか？）。AWS以外の多くの試験は前者の１つだけでOKな気はしますが。

# 実際に手を動かして体験する

[Auth屋さん](https://www.authya.com/)の教材を使用させてもらいました。

- [【電子版】雰囲気でOAuth2.0を使っているエンジニアがOAuth2.0を整理して、手を動かしながら学べる本](https://booth.pm/ja/items/1296585)
- [【電子版】OAuth、OAuth認証、OpenID Connectの違いを整理して理解できる本](https://authya.booth.pm/items/1550861)

多くの人が、各種説明サイトなどを読んだだけでは漠然としたイメージしか身に着かず、かつその記憶は長い間保たれないと思います。実際に手を動かして体験する事が重要です（※資料を読んだだけで理解できる凄い人もたまにはいると思います）。
また、ライブラリを使ったりするだけでは複数の役割（処理ポイント？）での情報のやり取りは一瞬で終わるのでなかなか把握できません。この状況が「雰囲気でOAuth2.0を使っている」状態だと思います。

これらの書籍では`Google Photo のリソースの取得`などの課題を、チュートリアル形式で、curlを駆使してフェーズ毎に一つ一つ体験できます。OAuthと関わる事になったエンジニアの方に強くお薦めできます。

※こちらの２冊はフリーではなく有料なので、私の記事での引用は立ち読みで見るレベルに留めさせてもらいます。詳しくはこちらの書籍購入でお願いします。ちなみに私はAuth屋さんの関係者ではありません。

## 雰囲気でOAuth2.0を使ってるエンジニアがOAuth2.0を整理して、手を動かしながら学べる本

OAuth2.0は、認可に関わるものです。前述のClassmethodさんの記事の表現を使わせてもらうと、`「鍵の発行」や「チケット（切符）の発行」`をする仕組みになります。
OAuthの話をすると、`クライアント`、`リソースサーバー`、`認可サーバー`など用語が出てきます。私のこの記事では詳細には説明しませんが、それらの用語のイメージをしっかりさせておかないと複数人で話をする時には迷子になります。この書籍のチュートリアルを経て、どのサーバーが何をどう送受信するのか、どの用語はどのような事を指しているのかを把握する事が出来ます。

※後述の教材をやる上で前提にもなります。

## OAuth、OAuth認証、OpenID Connectの違いを整理して理解できる本

今回の目標のそのものです。本書から引用させて頂きますと、以下の違いがあるとの事です。

> - OAuth は権限委譲のプロトコル
> - 「OAuth 認証」と呼ばれるものはプロフィールAPI による認証
> - OpenID Connect はID トークンによる認証

そして本書ではそれが理解できる本になります。自分はここを最初に読んだ時にはこの文章だけではどんな違いなのか理解できませんでした。こちらの本も一冊目と同様にチュートリアルでcurlを駆使して１ステップ１ステップで実行しながら動作を感じる事が出来ます。

### OAuth認証に関する自分の理解

チュートリアルを経て、自分なりに理解した所だと以下のポイントになります。

- Facebookなどの主要SNSはOpenAPIによる認可を提供している
- その主要SNSがリソースサーバー（認可情報により情報を提供する元）として、ユーザーのプロフィールを提供している
- そのプロフィール取得エンドポイントは`/me`エンドポイントと呼ばれる
- そのエンドポイントからプロフィールが取得できた事により、そのユーザーがログインした（認証した）と判断する
- アプリで表示するユーザー名などもここから取得出来る
- アプリ側での実装が甘いとセキュリティホールが出来る（なので怪しいサイトやアプリはまずい）
- Facebookはdebug_tokenエンドポイントを用意していて、なりすましチェックに使える

### OpenID Connectに関する自分の理解

同じく以下のポイントになります。

- OpenID ConnectはOAuthの拡張規格なのに用語が異なる
- openid、profile、email、address、phoneの５つのスコープが定義されている
- openidスコープが重要。これがOpenID Connectの要求
- 認証の為にIDトークンを使用する。形式は「[JWT](https://jwt.io/)」
- アクセストークンも使用する
- IDトークンにはSUBと呼ばれる情報領域にユーザー識別子が格納されている
- アクセストークンを使って、専用のUserInfoエンドポイントへアクセスしてユーザー情報を取得出来る
- IDトークンのユーザー識別子と、UserInfoエンドポイントから取得した情報の整合性を確認する事でアプリはユーザー認証が出来る

### その他：脆弱性に関して

世の中で話題になってるなりすましログインに関してに関してもどんな仕組みで行われているかを説明してくれています。
怪しいサイトやアプリを使うのが危険である事が良く解ります。
ここでは一例でしたが、Auth屋さんの次の著書「[OAuth・OIDC への攻撃と対策を整理して理解できる本（リダイレクトへの攻撃編）](https://booth.pm/ja/items/1877818)」ではさらに詳しい例が載っていそうです。「リダイレクトへの攻撃編」と言っているぐらいなのでさらに種類があるはずです。

# 手を動かさず理解したい方は

用語とか概念を解りやすく説明してくれています。各記事には、その道のプロフェッショナルである同著者によるより深い情報への記事リンクがありますので、必要に応じて参考に出来るかと思います。

[一番分かりやすい OAuth の説明](https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be)
[一番分かりやすい OpenID Connect の説明](https://qiita.com/TakahikoKawasaki/items/498ca08bbfcc341691fe)

実際にアプリなどを実装する方は手を動かして理解した方が良いかと思いますが、手を動かす前に概念だけでも理解したいとか、実装する人と話するので用語などの意識を合わせておきたいという方にお薦めです。

# まとめ

「[よくわかる認証と認可](https://dev.classmethod.jp/articles/authentication-and-authorization/)」を真似てメタファを自分なりに考えてみました。

:::note info
試験で、本人確認して受験票を発行するのが（認証に基づく）認可、試験会場で受験票を申し込んだ本人である事を確認をするのが認証
:::


違うかな？

# 次回予定

次こそはSAMLの事を何かやりたい。