ある日、REST APIの認証方法をまとめる(という話を聞く)機会があったのですが、要件と各社の実装方法を照らし合わせるとさまざまなケースが存在して興味深かったので、ブログにまとめてみることにしました。

#OAuthは「認証」ではなく「認可」の機構であるとか、人の認証とプログラムの認証がごっちゃになってたり、いろいろツッコミどころの多い内容かと思いますがご容赦を。。

求められていた要件(と検討ポイント)

  1. Webアプリ以外にバッチプログラムからの利用も想定したい
  2. 通信経路中での盗聴や改ざんを防止したい
  3. APIトークンの発行などのアカウント管理の手間を軽減したい
  4. キーやトークンが漏れた場合の対策をどうするか

1については、特に後者の場合だとPINやOut-of-band(OOB)方式が使えそうですが、「それだと初回やセッション切れた時ににブラウザなど別の認証入るよね?」(いわゆる”火入れ”)とか、「HTTPS必須にすれば経路中の盗聴や改ざんは防止できるけど、本当に?」(まぁMITM攻撃とかありますしね。。)という会話の後、MAC(Message Authentication Code)トークン署名方式ならどうかという流れに。

署名付きリクエストはOAuth 1.0aでHTTP通信の時に使われますが、いかんせんデバッグが大変なのと、MACトークン署名方式でもkeyとsecretが漏れたら結局一緒の様な気がしてモヤモヤしてました。

#てかOAuth 2.0にMACトークン署名方式は無いでしょ、と思ったら一応仕様としてはあるらしい
OAuth 2.0 MAC Tokenを使った署名付きリクエストの作り方 - r-weblife

既存REST APIの認証方法

前置きが長くなりましたが、ではネット上で既に提供されているREST APIはどのような認証方法を提供しているのかを調べてみたのが以下になります。

Twitter
dev.twitter.comでアプリケーションを登録して、そこで発行されるAPIキーまたはアクセストークンをプログラムで使う。OAuth1/OAuth2対応。

Facebook
developers.facebook.comでアプリケーションを登録して、そこで発行されるアプリケーションIDとアプリケーションキーをプログラムで使う。OAuth2のみ対応。

Google
console.developers.google.comでアプリケーションを登録して、そこで発行されるクライアントIDとクライアントシークレットをプログラムで使う。OAuth2のみ対応(OAuth1は非推奨)。

Amazon AWS
AuthorizationヘッダとHMACハッシュ署名による認証。最近、署名で使うアクセスキーはルートのものは取得できなくなった(IAMで権限を指定したユーザを作成する)。

GitHub
BASIC認証とOAuthトークンによる認証。OAuthトークンの発行はアプリケーション用と個人(アカウント)アクセス用?に分かれている。

Parse
アプリケーションIDとクライアントキーによる認証。クライアントキーはREST API用の他にJavascript用や.NET用など用途別に発行される。

OAuth2が多いものの。。

ざっと既存のREST APIでは、OAuth2 Bearerトークンによる認証が多く、”経路中の盗聴や改ざんはHTTPSで担保し、トークン漏れは生存期間を短くする事で対処する”というOAuth2のセキュリティ要件に従った形が多いようでした。
(加えて、管理コンソールからのキーのrevokeやregenerateなど)

ただ、認証ヘッダはAuthorizationやベンダープリフィックス(X-HOGEHOGE)を使う場合とさまざまで、キー名の呼び方も各サービスでまちまちでした。また、モバイルアプリなどHTTPS+OAuth2 BearerトークンとHTTP+OAuth1署名で通信のオーバーヘッドはどちらが軽いかなども検証する必要があるかもしれません。