Basic認証とOAuth

Basic認証とOAuthとその辺の情報について整理しておく。OAuthや認証・認可について説明しようとすると、1文字記述するたびに誤りが含まれてしまう可能性があるので、本当に緊張感を持って記述しなければならない。それでもなお、この文章にはたくさんの誤りが含まれている。

Basic認証

UsernameとPasswordを受け取って認証する形式の認証方法。UsernameにはEmailを使うこともある (要は全ユーザの中で一意なことが保証されていてかつ他の人がその値を知っていても特に問題がないという情報であればOK)。Passwordは本人しか知り得ない情報。

OAuth

OAuthという仕様に則って提供される認可方法。古いOAuth 1.0と、OAuth 1.0の複雑なところなどを改善したOAuth 2.0がある。一般的にはOAuth 2.0を使うことが多いが、例えば幾つかのサービスの提供している認可方法はOAuth 1.0であったりする。OAuth 2.0はRFC 6749で定義されているが、認可機能を提供する側に仕様の選択の余地が多いため、一言で「OAuth 2.0に対応している」と言っても同じ機能を提供している訳ではない。

第三者のアプリにPasswordを渡さなくてよくなる

OAuth 2.0では用途によって数種類の認可方法を提供しても良いことになっている。例えばWebアプリ用には、Authorization Code Grantフローと呼ばれる認可方法がある。Webアプリからリダイレクトしてきて本家サービス側でUsernameとPasswordを入力し、本家サービスからURLに特別なコードを付与した状態で元のWebアプリにリダイレクトし、Webアプリからコードを返送してアクセストークンと交換する、というフロー。Authorization Code Grantフローを利用すると、Webアプリの利用者は本家サービスにしかPasswordを入力する必要がない。そのため、末端のユーザにとっては「Basic認証に比べて安心してWebアプリを利用できる」という利点がある。

いちいちクライアントを登録するのが面倒でもある

Basic認証は非常にシンプルな仕組みなので、理解しやすく使いやすい。勿論OAuth 2.0でも、UsernameとPasswordを送ってアクセストークンと交換してもらう、Resource Owner Password Credentials Grantと呼ばれるフローを提供しても良いことになっている。しかし、このフローではUsernameとPasswordの他にClient IDとClient Secretも同時に送らなければならないから、つまり少しだけAPIを利用してみたいという場合にいちいちクライアントを登録する必要がある。

GitHubは両方提供している

GitHubでは、OAuth認可もBasic認証も両方提供している。というか「両方提供している」という言葉では表現しきれなくて、実際にはUsernameとPasswordだけでOAuthのアクセストークンを発行することができて、これはGitHubでは「Personal access token」と呼ばれている。https://github.com/settings/applications で確認できるものがそれ。Personal access tokenは、管理画面からWebブラウザ経由でも発行できるし、APIを通して発行することもできる。

また、アクセストークンを渡さずにAPIを利用できるようにもなっている。この場合、リクエストヘッダにUsernameとPasswordを含めながらAPIにリクエストを送ることになる。ちなみに、Basic認証を使おうがOAuth認可を使おうが、特にRate Limitには影響が無い。「あるユーザは1時間に5,000回までAPIにリクエストを送れる」というルールは守られている。

以下はGitHubのPersonal access tokenに関する説明。

Personal access tokens are useful when it's too cumbersome to provide a client/secret pair for a full application, such as when authenticating to GitHub from Git using HTTPS, or within a command line utility or script.

:octocat: < だるいとき便利!

IPAはこう見る

4つのグラント種別のうち、どれを選択すべきであろうか? ...(中略)... 結局のところ、Authorization Codeグラント種別を用いるのが最も無難である。 クライアントマシンで動作する独立アプリケーションであっても、Resource Owner Password Credentialsグラント種別ではなく、Authorization Codeグラント種別を用いている例がある。そこでは、プログラム中からブラウザを起動し、リソース所有者が直接Authorization Serverから認証を受けられるようにしている。

https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/709.html

クライアントアプリでは問題が深刻である

もしクライアントアプリが安全なブラウザではなくWebView経由でAuthorization Code Grantフローを利用していたとすれば、何らかの方法でWebViewをユーザの入力したパスワードを傍受することも可能である。「あれ?デフォルトのブラウザに飛ばされずにアプリの中でブラウザが起動したぞ?なんか怪しいな?」という疑いをユーザがもっていれば可能だが、ユーザにそこまでは望めないだろう。まあそもそも「安全なブラウザ」というのが存在していればという話だが。