認可と認証を整理する。あるいはややこしい名称の話

# はじめに

n番煎じだが混同されやすい認可と認証を整理する。

認可・認証サーバーとしてGoogleを使うことを検討しているので、例示や実装においてはGoogleを引き合いにして説明する。

整理の過程でOpenID ConnectとGoogleのOAuth 2.0 APIサービスにおけるややこしい名称の話にブチあたったのでそちらも書いておく。

# 認可と認証

## 認可（authorization）

権限を与えること。

たとえばプロフィール情報への認可が与えられるとアプリがGoogleアカウントの氏名へアクセスできたり、メールへの認可GMail内に保存されているメールを読み取れたりする。

## 認証（authentication）

本人であるとお墨付きを与えること。

たとえばTwitterにログインする時にGoogleアカウントのユーザー名とパスワードを入力すればログインできるのはTwitterがGoogleから認証をもらっているから。

# ユースケースにみる認可と認証

## 前提

あるサービスA・B・Cにユーザーアカウントを作る時のことを考える。
サービスA・B・Cでアカウントを作る時、他サービス連携なしだと、ユーザーはサービスA・B・Cのいずれに対しても氏名とユーザー名とパスワードを入力（設定）する必要があるサービスだったとする。

さて、それぞれのサービスでアカウントを作る時、Googleと連携させて作ることにした。

## サービスAの場合

### 状況

サービスAでGoogle連携を選ぶと、Googleのログイン画面に飛ばされGoogleへのログインを要求されたのでログインした。
その後、サービスAの画面に戻ってきて、サービスAで使うパスワードの設定を要求されたので入力した（氏名とユーザー名の設定は要求されなかった）。
最終的にアカウントが作成され、サービスAにはGoogleアカウント名（Gmailアドレス）とサービスAで設定したパスワードの入力でログインできるようになった。
ログイン後のプロフィール画面では自分の氏名が設定されていた。

### 考察

サービスAではGoogleに対して認可の仕組みだけ使っていると推測できる。

サービスAはGoogleアカウントの情報へアクセスできるので、以下のようにユーザー名と氏名をGoogleアカウントから取得した。

- Googleアカウント名（Gmailアドレス）を入手 -> ユーザー名として自分のDBにコピー
- Googleアカウントが持つ氏名情報を入手 -> 氏名として自分のDBにコピー

よって、ユーザーはユーザー名と氏名は入力する必要がなかった。

一方、認可でできるのは情報へアクセスしてコピーすることだけなので、サービスAへのログインはサービスA自前のログインシステムを利用する必要がある。したがってパスワードだけはユーザーが入力する必要があった。

## サービスBの場合

### 状況

サービスBでGoogle連携を選ぶと、Googleのログイン画面に飛ばされGoogleへのログインを要求されたのでログインした。
その後、サービスBの画面に戻ってきて、氏名の設定を要求されたので入力した（ユーザー名の設定とパスワードの設定は要求されなかった）。
最終的にアカウントが作成され、サービスBにログインする時は都度Googleにログインすることでログインできるようになった。
ログイン後のプロフィール画面では自分の氏名が設定されていた。

### 考察

サービスBではGoogleに対して認証の仕組みだけ使っていると推測できる。

サービスBはGoogleを使ってユーザーの同定を行うことができるので、サービスB自前のログインシステムを使う必要がない。よって、ユーザーはユーザー名やパスワードを入力する必要がなかった。

一方、サービスBはGoogleアカウントの情報へのアクセスはできない。したがって、氏名はユーザーに入力させる必要があった。

ちなみに、この方式がいわゆるシングルサインオン（SSO）である。

## サービスCの場合

### 状況

サービスCでGoogle連携を選ぶと、Googleのログイン画面に飛ばされGoogleへのログインを要求されたのでログインした。
その後、サービスCの画面に戻ってきてアカウントの作成が完了した（氏名の設定、ユーザー名の設定、パスワードの設定は要求されなかった）。
サービスCにログインする時は都度Googleにログインすることでログインできるようになった。
ログイン後のプロフィール画面では自分の氏名が設定されていた。

### 考察

サービスCではGoogleに対して認可と認証の仕組み両方を使っていると推測できる。

サービスAとサービスBの説明の繰り返しになるため、詳細は省略。

この方式もSSOである。

# プロトコル

2022年現在、認可を主目的とするプロトコルで最も有名なのはOAuth 2.0、認証を主目的とするプロトコルで有名なのはOpenID ConnectとSAMLだろう。
それぞれ詳しい内容は割愛する。

ところで、OpenID Connectには名称にまつわるややこしい話題がある。

OpenID ConnectはOpenID財団が管理する仕様である。
OpenID財団は今までに以下のようなプロトコルを開発してきた。

* [2022年現在既にDeprecated]OpenID Authentication 1.0
* [2022年現在既にDeprecated]OpenID Authentication 2.0
* OpenID Connect

OpenID AuthenticationシリーズとOpenID　Connectの間では仕様上の繋がりが薄く、明確に区別する必要があるのだが、インターネットやプログラミングの世界ではこの呼称がややこしい。

OpenID財団ではOpenID Authentication 2.0を指して「OpenID　2.0」と呼び、OpenID Connectはそのまま「OpenID　Connect」と呼ぶようにしている。
これを受けて、多くのウェブサイトでは単に「OpenID」というとOpenID Authenticationのことを指すことが多いが、少数ケースではOpenID AuthenticationシリーズとOpenID Connectを全て引っくるめたものを「OpenID」と呼ぶこともある。
OpenID Connectはやはりそのまま「OpenID Connect」と呼ばれることが多いが、事情をよくわかっていないウェブサイトでは「OpenID」と呼んでいる例も見られた。

プログラミングの世界では、OpenID Authenticationの符号として「OpenID」か「OID」、OpenID Connectの符号として「OIDC」を使うことが多い（気がする）。

# GoogleのOAuth2.0 API

GoogleのOAuth2.0 APIはOAuth2.0プロトコルに準拠するAPIである。

実はこのOAuth2.0 APIも名称にまつわるややこしい話題がある。
このOAuth2.0 API、「OAuth2.0」という名詞がついているがが実はOAuth2.0プロトコルだけでなくOpenID Connectプロトコルにも準拠している。つまり、GoogleのOAuth2.0 APIは認可だけでなく認証の能力も持っているのである。
（このことは[公式](https://developers.google.com/identity/protocols/oauth2/openid-connect)の最上段にも書いてあるがマアややこしい。）

Googleを使ったシングルサインオンを作る場合このOAuth2.0 APIを利用することになるのだが、「OAuth」という名詞からOAuthプロトコル自体が認証機能を持っているかのような誤解を与えている。やめてほしい。

# おわりに

適宜追記する。