目的
前提
- APIは既に存在し自社webアプリケーションから利用されている。webアプリからの認証には client credentials認証フローを採用している。
- REST API
- APIリクエスト時には、アクセストークンを必須としている。アクセストークン未発行の場合アクセストークンの発行を行う必要がある。
- 第3者へのAPI公開はまだ考えていないため、サードパーティーアプリからの認証は考えなくて良い。
- なるべく時間はかけたくない
やったこと
OAuth 認証フローについて調べてみると、RFC文書内に認証フローは4種類定義されていおり、その中の Resource Owner Password Credentials Grant が API認証フローとして今回の要件をみたす形で利用できる判断し実装した。
Resource_Owner_Password_Credentials_Flow
+----------+ | Resource | | Owner | | | +----------+ v | Resource Owner (A) Password Credentials | v +---------+ +---------------+ | |>--(B)---- Resource Owner ------->| | | | Password Credentials | Authorization | | Client | | Server | | |<--(C)---- Access Token ---------<| | | | (w/ Optional Refresh Token) | | +---------+ +---------------+ Figure 5: Resource Owner Password Credentials Flow The flow illustrated in Figure 5 includes the following steps: (A) The resource owner provides the client with its username and password. (B) The client requests an access token from the authorization server's token endpoint by including the credentials received from the resource owner. When making the request, the client authenticates with the authorization server. (C) The authorization server authenticates the client and validates the resource owner credentials, and if valid, issues an access token.
RFC 6749 - The OAuth 2.0 Authorization Framework
この認証フローでは、トークン発行時のリクエストに、username, password を指定する。そのusername, password の組み合わせが有効だった場合、有効なリクエストだと判断しアクセストークンを発行する。
実際のフロー
- モバイルアプリのログインフォームにユーザがusername(ID), passwordを入力する。このusernameとpasswordはアプリケーションのユーザログイン時に使うものと同じ。
- それをもとにモバイルアプリがAPIトークン発行リクエストをAPIへ送信する。
- APIでusername, password の組み合わせをDBと照合し、正しければアクセストークンを発行する。
- 以後そのアクセストークンでモバイルアプリはAPIリクエストを送信する。
ユーザによるリソースへのアクセス制限
モバイルアプリからリクエストパラメータを改ざんして送信されることは起こり得る。 例えば、ユーザ情報変更APIをモバイルアプリから利用するとする。ユーザIDによるリソースのアクセス制限を設定してない場合のリクエストパラメータを他人のIDに書き換えてリクエストを送信されると他人のリソースが変更できてしまうという重大な脆弱性になる。
この問題を回避するために、
- アクセストークン発行時に ユーザIDを発行したアクセストークンと紐付けて保存する
- 個人情報を扱うAPIリソースへのアクセス時には、そのアクセストークンを発行したユーザIDとAPIで参照しようとしているユーザIDが一致しているかチェックする。一致している場合はアクセスを許可、一致していない場合はアクセスを拒否しエラーを返す。
まとめ
この認証フローはモバイルアプリケーションがユーザのアプリケーションへのログインID, passwordを知る必要がある。つまりログイン情報を知っても問題ないアプリケーションから利用する場合に限られる。なので自社製アプリなど信頼できるアプリケーションにこの認証フローは使えない。
認証フローに限らずAPI設計を考える上で、Web API: The Good Parts にはかなりお世話になった。良書。
- 作者: 水野貴明
- 出版社/メーカー: オライリージャパン
- 発売日: 2014/11/21
- メディア: 大型本
- この商品を含むブログ (7件) を見る
利用したライブラリとか
GitHub - bshaffer/oauth2-server-php: A library for implementing an OAuth2 Server in php