OAuth 2.0 のプロバイダを作るんだったら、もしかして認可権限の取消画面も作らないといけないのかしら〜〜〜〜(ほげ〜〜〜〜)と思って調べてたら、その revoke の仕様も RFC で仕様化されていることを知りました。 これにより、必ずしも取消画面を作らなくて良いということにはなりませんが、API として公開することは容易そうなので心をなでおろしています。
OAuth 2.0 (RFC 6749) では認可サーバ側での認可権限の無効化について触れられていますが、RFC 7009 で触れられているのは、クライアントからの権限の無効化です。 Twitter における「アプリ連携」メニューでは、個々のアプリケーションに対して「許可を取り消す」というボタンが存在していますが、あれを仕様化したものと理解すれば良い。
トークンの無効化という文脈には以下の 2 つがあります。
- リフレッシュトークンの無効化
- アクセストークンの無効化
このうち、絶対に実装せよ(MUST) とされているのはリフレッシュトークンの無効化です。アクセストークンと比較して、リフレッシュトークンの有効期限は一般に長い (あるいは無期限) ので、これは当然といえば当然ですね。アクセストークン無効化したって、リフレッシュトークンが有効なままなら、新しいアクセストークンの再取得が可能ですし。
一方でアクセストークンの無効化は、アクセストークンを JWT で実装するといったケースでは非常に困難なものになります。このようなケースでは、アクセストークンの有効期限を短くして対応することになるでしょう。
Token Revocation
トークンの無効化に際して、認可サーバは「Token Revocation EndPoint」を実装する必要があります。これは一種の無効化 API のエンドポイントと考えてもらったら良さそうです。 クライアントは、認可サーバに以下のようなリクエストを送ります。
POST /revoke HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token
Token Revocation Endpoint の仕様の概要としては、
- HTTPS で提供する (TLS のバージョンはもちろん新しいやつをつかいましょう)
- POST メソッドを受け付ける。パラメータは後述。
- クライアント認証は実施。(RFC 6749 参照)
POST メソッドのパラメータは以下のようなものになります。
パラメータ名 | REQUIRED/OPTIONAL | 概要 |
---|---|---|
token |
REQUIRED | 無効化したいトークン |
token_type_hint |
OPTIOAL | ※後述 |
このうち、token_type_hint
は、リフレッシュトークンを無効化するのか、アクセストークンを無効化するのかのヒントを示しています。仕様上は access_token
、refresh_token
が定義されていることもあり、基本的にはこの 2 値を使うことになるでしょう。
認可サーバ側はリクエストを受け取り、トークンを無効化したら、HTTP レスポンス 200 を返却します。この後、クライアント側は無効化したトークンを使ってはいけません(使ってもエラーになりますが)。
おもしろいのは、無効なトークンに対する無効化要求に対しても、認可サーバは HTTP ステータス 200 を返却する点です。 たしかに、このケースでクライアントに 4XX や 5XX を返却しても、クライアントは何ができることはありませんね。
リフレッシュトークンの無効化は、紐づくアクセストークンの無効化を要求するか
悩ましいのは、リフレッシュトークンを無効化したとき、そのリフレッシュトークンから作成されたアクセストークンを無効化しないといけないかどうかですが、RFC 的には「アクセストークンの無効化をサポートしているのであれば、リフレッシュトークンの無効化でアクセストークンも無効化すべきでしょ (SHOULD)」という立場です。 JWT とかでアクセストークンを構成する場合はアクセストークンの無効化自体が困難なケースが多いので、そういう場合は、アクセストークンは「Expire するのに任せる」というのが良いかなと思います。