よくわかる認証と認可

よくわかる認証と認可
514件のシェア(そこそこ話題の記事)

よく訓練されたアップル信者、都元です。「認証 認可」でググると保育園の話が山程出て来ます。が、今日は保育園の話ではありません。そちらを期待した方はごめんなさい。こちらからお帰りください。

さて、先日のDevelopers.IO 2016において、マイクロWebアプリケーションというテーマでお話させて頂きました。一言で言うと OAuth 2.0OpenID Connect 1.0 のお話だったのですが、これらを理解するにあたっては「認証」と「認可」をはっきりと別のものとしてクッキリと認識する必要があります。

まず、ざっくりとした理解

認証と認可は密接に絡み合っている一方で全く別の概念です。正直、理解は簡単ではないと思います。

まず「認証」は英語では Authentication と言います。長いので略して AuthN と書いたりすることもあります。意味としては 通信の相手が誰(何)であるかを確認すること を表します。純粋な「認証」を考えるにあたっては「リソース」やそれに対する「権限」という概念は登場しません。

一方「認可」は英語では Authorization と言います。略して AuthZ(AuthRと書く場合もあるらしいです)です。意味としては とある特定の条件に対して、リソースアクセスの権限を与えること を表します。純粋な「認可」には、「誰」という考え方はありません。

認証と認可の密結合

とは言え、古くから認証と認可は密に結合した概念として捉えられてきました。

  • 相手はadminさんだから、アクセスが許可される。
  • 相手はadminさんではないから、アクセスは許可されない。
  • アクセスが許可されるということは、相手はadminさんだ。
  • アクセスが許可されないということは、相手はadminさんではない。

このように逆・裏・対偶が全て成り立つことはあまりないかもしれませんが、「相手の確認」と「権限の決定」がほぼ同義でした。

先ほど、純粋な「認可」には「誰」という考え方はない、と言い放ちましたが、それでも多くの場合、認可は認証に依存しています。つまり「とある特定の条件」というのが「相手が特定の誰かであることが認証されている」という条件であることが多いのです。

ただしこのような条件は後で触れるので、ひとまずは認証と認可を切り離しにかかりましょう。

認証と認可の分離

そんな中、一昔前の話になりますが「マッシュアップ」「Web2.0」という考え方が隆盛し、本来人間が持つ権限を、外部システムに委譲する仕組みが勃興しました。これがOAuthです。

例えば TwitterTogetter の関係を考えてみましょう。

Togetter というサービスは、Twitterユーザ(例えば@daisuke_m)に成り代わって(@daisuke_mの名の下に)Twitterに対してTweetというリソースの操作をします。Twitterからしてみれば、通信の相手は Togetter である一方、持っている権限は@daisuke_mのものです。認証と認可の間に食い違いがある状態ですね。

これは、@daisuke_m が Togetter に対して「認可の委譲」を行った結果です。Togetterに対してIDとパスワードを渡してしまい、「認証の手段」を丸ごと渡してしまうわけでなく、@daisuke_m が持っている「認可」だけを渡しているのがポイントです。

認証(Authentication)

あらためて、認証というのは 通信の相手が誰(何)であるかを確認すること です。

理解を助けるメタファは「証明書の確認」です。もっと具体的には、今話題のマイナンバーカードを使った本人確認をイメージしてみてください。

純粋な認証は、それが完了したからといって何かが許される話とは関係がありません。

例えば、私にあなたのマイナンバーカードを提示して、そこに「山田太郎」と書いてあった場合、私は目の前にいる人が山田太郎さんであることを認めると思います。でも、それだけです。こんにちは、山田太郎さん。(にっこり)

認証の3ファクター

コンピュータの世界も含め、現実世界で「認証」を行うための要素には以下の3つがあります。

1. WHAT YOU ARE (inherence factor)

顔貌、声、指紋、署名など、その人自身を提示して、相手にアイデンティティを確認させる方法です。小さなコミュニティでは、お互いの顔や声を相互に知っているため、面と向かえば相手が誰かはわかりますね。認証が完了する、ということです。

2. WHAT YOU HAVE (possession factor)

身分証、携帯電話等、その人だけが持っているものを提示することによって認証をします。ある程度コミュニティが大きくなってくると、お互いの特徴を覚えきれなくなります。そんな場合は身分証明書を提示して、相手を認証すると思います。

また、その身分証には顔写真がプリントしてあることも多く、結果として WYA に依存するものも少なくありません。

3. WHAT YOU KNOW (knowledge factor)

パスワード、秘密の質問等、その人だけが知っていることを提示して認証をします。コンピュータの世界で最も多く使われるファクターでしょう。

一般的に、上記3つのうちいずれか1つを満たすことで、認証が完了することが多いです。しかし、より確実な認証を行いたい場合は、Multi-Factor Authentication (MFA) という考え方で、複数のファクターを確認することもあります。

ちなみに「自分は誰なのか」とか「あなたと私は違うのか」とか「昨日の自分と今日の自分は同一人物か」とか「そもそも "同じ" とは何か」とか「人間による顔の "記憶" は確かなのか」とか言い出すと、哲学ゾーンに入っていくっぽいので気をつけましょう。Yes、我らはエンジニア。

ほら、もう、APIとかリソースとか権限とか関係ないでしょう。これが認証です。

認可(Authorization)

あらためて、認可というのは とある特定の条件に対して、リソースアクセスの権限を与えること です。

理解を助けるメタファは「鍵の発行」や「チケット(切符)の発行」です。

純粋な認可は、それがあるからといって身元が明らかになる話とは関係がありません。

駅で切符を買いました。あなたは電車に乗ることを許されます。それだけです。あなたが誰かは関係ありません。

また、誰かから購入済みの切符をもらいました。これでもあなたは電車に乗ることができます。委譲されたんですね。

認可は、それを持っていることによって何か(リソースアクセス)が許されます。ドアは鍵を持っていれば開くし、持っていなければ開きません。繰り返しますが、あなたが誰かは関係ありません。

先ほど「多くの場合認可は認証に依存している」と言いましたが、これが、認証に基づかない認可の事例です。

認証と認可の分離に関する疑問

認証せずに認可することなんてあるのか?

あります。上の切符の例がそれにあたりますね。

その他、iptablesの設定で特定のIPアドレスからのリクエストを許可する、なんていうのも認証に基づかない認可です。IPアドレスによって、相手のアイデンティティが確定するとは限りませんね。

認証したのに認可しないことなんてあるのか?

1つのシステムに閉じて考えている限りは、まず ない と考えて良いでしょう。何のために認証したんだ、ということになります。

しかし OpenID Connect等、認証の委譲が発生するような分散環境においては複雑な事情がありえます。

マクロな視点では「Aシステムがユーザの認証を行い、その事実をBシステムに通知した」という状態において、Aシステムは認証をしたが、認可はしていないことになります。

一方ミクロな視点では「BシステムはAシステムからユーザを認証したことを通知された。だからBシステムは独自で持つリソースへのアクセスを許すことにした」ということがあるかもしれません。恐らく、あるでしょう。

しかしそれはミクロの話で、マクロレベルでは認証しただけ。認可したかどうかは 知らん のであります。

メタファで考えると、マイナンバーカードを使ってレンタルビデオ店の会員権を得る話 *1。マイナンバーカード自体は何も認証をしていません。が、レンタルビデオ店がマイナンバーカードに基いて認可をしています。その状態について、公的機関は「知らん」のです。

認証に基づく認可

これが、多くの人が考える認証と認可のパターンです。これ以外のパターンをクッキリと認識しないと、世の中の全てがこのパターンのように思えてしまい、認識が密結合しちゃうんですね。

で。認証に基づく認可のメタファは「運転免許証」でしょうか。免許証は、写真によりある人が誰であるかを証明し、その上で、その人に対して運転の認可をしています。

切符のように、誰かに渡しても受け取った人が運転を許されたりはしません。なぜならこの認可は、認証にもとづいているからです。

認可に基づく認証(!?)

認証と認可の密結合パターンには、こんなものもあります。

この人は都元家の家のドアを開ける鍵を持っているから、都元さんである。

認証してもらうために、相手に自分の家の鍵を渡すのです。現実ならば鍵を返してもらえば大事には至らないと思いますが、これがコンピュータの世界のトークンであった場合、コピーが相手の手元に残る可能性があります。

どう思いますか?

この仕組みは、いわゆる「OAuth認証」と言われるものです。OAuthはあくまでも認可の仕組みであり、認証には関係無い、というのが正式な立場です。

上記のように、実際に認証が成り立ってしまうのは事実ですが、「認証したいだけなのに家の合鍵を渡すってどうなの?」とか「そもそも鍵を持ってるからといって、その本人であるとは限らないのでは?」等、様々な問題が発生する可能性があります。

非対称的な並列比較に注意

さて、以上が認証と認可の切り分けに関する解説です。

ここまで比較しておいてアレなんですが、認証と認可というのは相互に比較するにあたって「対称性」が無いと思っています。

先ほど、認証は証明書、認可は鍵、というメタファを示しました。これらのメタファは「発行」と「検証」という段階があると思います。

認証というのは、証明書発行の瞬間ではなく、提示された証明書を検証する瞬間のことを言います。

一方で、認可というのは、鍵発行の瞬間(正確に言えば、アクセスポリシー定義段階)のことを示しており、提示された鍵を検証するタイミング(アクセスポリシー施行段階)を指すわけではありません。

難しいですね。。。

脚注

  1. 現実世界ではやっちゃいけないようですが。。。