ウェブシステムの設計やセキュリティの話になると、「認証(Authentication)」と「認可(Authorization)」が必ず顔を出す。字面がよく似ているので、しばしば混同される。なにしろ二文字のうち一文字が同じなのだ。取り違えるなと言うほうが、いささか酷である。
言葉を取り違えるだけなら、笑い話で済む。厄介なのは、二つを混ぜたまま設計してしまった場合だ。それは重大なセキュリティリスクに直結しかねない。そこで、改めて違いと関係を整理しておくことにした。
一言で片づけるなら、認証はユーザーが〈誰か〉を確かめることだ。対して認可は、そのユーザーが〈なにをしてよいか〉を決めることである。オフィスビルにたとえると、前者は受付、後者は入館証で開くドアの範囲にあたる。以降、このビルの見立てで話を進める。
受付としての認証
認証は、ビルの受付で身分証を見せる手続きに相当する。アクセスしてきた相手が、自称している通りの人物なのかをシステムが確かめるのだ。目的は身元の特定であり、それ以上でも以下でもない。
手段はいくつもある。メールアドレスとパスワードによるログイン、Google や GitHub のアカウントを使った OAuth ログイン、指紋や顔による生体認証などだ。とはいえ、どれも行き着く先は同じである。「このリクエストを送っているのはユーザー A さんだ」と確定させることに尽きる。
入館証としての認可
一方の認可は、権限の付与と判定である。特定のユーザーが、あるリソースに対して閲覧・編集・削除のどれを許されているのかを決める。入館証をかざしても、開くドアと開かないドアがあるのと同じ理屈だ。こちらの目的はアクセス制御になる。
ルールの例には事欠かない。管理者だけがユーザーの削除ボタンを押せる。ログイン済みでも、他人のプライベートな日記は見られない。有料プランのユーザーだけが、高度な分析機能を使える。これらはすべて認可の領分であり、下されるのは「A さんは、このデータを削除してよい(あるいは、だめ)」という判定なのだ。
順序と落とし穴
一般的なアプリケーションでは、まず認証でユーザーを特定し、次に認可で権限を確かめる。「君は A さんだね」と身元を確認したうえで、「A さんは管理者ではないから、削除は禁止」と線を引くわけだ。受付を通してから、入館証の範囲で動いてもらう。順番としては至って穏当である。
肝心なのは、認証が通ったからといって認可が要らなくなるわけではない、という点だ。ログインできているのだから安全だろう、と高を括って認可のチェックを怠る。すると、一般ユーザーが管理者用の API をしれっと叩けてしまう。権限昇格の脆弱性、一丁上がりである。
受付で名前を名乗っただけの来訪者に、金庫室のマスターキーまで渡すような所業だ。ビルなら警備員が飛んでくるところだが、API は律儀に処理を進めるだけである。誰も止めてくれないのだから、止める仕組みは自分で書くしかない。
以上、認証と認可の違いを整理した。認証は受付での本人確認であり、認可は入館証で開けてよいドアの範囲である。受付を通ったことは、どの部屋にも入れることを意味しない。二つを別物として設計することこそが、安全なアプリケーションへの第一歩なのだ。