Authlete の OAuth 2.0 / OIDC 実装ナレッジ 完全に理解した

f:id:ritou:20151012214551j:plain

お疲れ様です。ritouです。

OAuth 2.0 / OIDC 実装の刺激が欲しくなったので(?)、Authlete 社が公開しているナレッジサイトの OIDC / OAuth 2.0 に関する部分を読むことにしました。 kb.authlete.com

この記事は、OAuth 2.0 / OIDC を完全に理解した上で Authlete というプロダクトについてなんとなくイメージがついていないとニヤニヤできないかもしれません。 Authlete は "サードパーティーアプリケーションから Web APIへのアクセス制御を行うために必要とされる『認可』の仕組みを提供するクラウドサービス" ですとどこかに書いてありました。

これは個人的な考えですが、RFCなどで定義された仕様を利用するプロダクトというのは、仕様で定義されている機能を設計/実装と、仕様で定義されていない部分や複数の仕様で定義されていて選択が必要な部分の設計/実装によって作られていると思います。

f:id:ritou:20181001013008p:plain

この、仕様で定義されていない部分の設計/実装というところが、そのプロダクトの立ち位置などにより与えられた要件をどのように解決しているのか、つまりナレッジであると考えています。 Authlete というプロダクトのナレッジから何か新しい発見があることを期待しながら、上から見ていきます。 なお、9/30頃に読んだものなので、それから更新されたりなんなりで差分が発生しても追従しない予定ですが、追記ぐらいはするかもしれません。

トークン管理

ユーザー単位での発行済トークン管理 — Authlete ナレッジベース (Beta)

実行例が紹介されていますが、APIリファレンスと重なるので、「 Authlete では発行済みの Access Token を操作する API があり、こんな用途に使えます」ってのを紹介する方が良い気がしますが、まぁそれは個人的見解です。

簡単に説明すると

  • ユーザーIDを指定して、有効な Access Token が発行済みの Client 一覧が取れる : 管理画面やユーザー向けの設定画面で「連携しているアプリケーション一覧」みたいな機能をつける時に使えそう
  • ユーザーID, Client ID, Scopeの値を指定して更新 : Scope定義の変更時などに整合性を合わせる時に使えそう(下の方に書いてある)
  • ユーザーID, Client ID を指定して、発行済みの Access Token 一覧を削除 : 「連携しているアプリケーション一覧」からの解除に使えそう

って感じでしょうか。

Authlete を利用するサービスが Access Token をハンドリングできるAPIを用意していますよということなので、例えばライブラリ開発者とかならこれを参考に似たようなメソッドを内部で用意しておくと便利かもしれません。

ハイブリッド・フロー: スコープを制限したアクセス・トークンの発行 — Authlete ナレッジベース (Beta)

  • 発行済みの Access Token の Scope を変更(狭められる)できるAPIがある
  • ハイブリッドフローで Client のフロントエンド / バックエンド向けに2つの Access Token を発行することができる
  • Authlete 利用サービスの認可サーバー・フロントエンドがScope更新APIを使ってフロントエンドむけのスコープを制限することができる

ちなみに ”Authlete 自身はスコープのサブセットを管理しません” とある、サブセット管理の例を上げておくと

  • Authorization Request で指定可能な Scope を管理する
  • そのうち、Implicit 的に渡す Access Token に付与していいかどうかをフラグで持つ
  • Authorization Endpoint から発行される Access Token にはフラグが立ってるやつだけ指定される

とかになって複雑になりそう。やらない選択に +1

一瞬、クライアントのフロントエンドが更新API叩くのか?って思ってしまったので、図があると良いのかも。 "Authlete 利用サービスの認可サーバー・フロントエンドが" と言うことは、Scope 広いアクセストークンが Client に戻される前に Scope を制限できるってことなので、リスクもないですね。

使用されていないトークンに関する Authlete の削除ポリシー — Authlete ナレッジベース (Beta)

  • 90日間利用されなかったトークンは消す
  • Access Token だけじゃなく Refresh Token も使われてなかったら消す

だそうです。

期限切れのアクセス・トークンに関するイントロスペクションの挙動 — Authlete ナレッジベース (Beta)

有効期限切れのAccess TokenをトークンインストロペクションAPIに投げたとき、

  • 初回は有効期限切れと言うレスポンスを返し、削除処理が走る
  • 2回目以降は存在しないレスポンスになる

トークンインストロペクションAPIがわからない? って人...つ RFC7662として発行されたOAuth Token Introspectionとは - r-weblife

リフレッシュトークンを継続利用する/しない — Authlete ナレッジベース (Beta)

例えばWebアプリケーションのログインセッションのポリシーは結構バラバラであり、

  • 一度ログインしたらずっとログイン状態
  • 最終アクセス日時から一定期間たつとログアウト
  • ログイン日時から一定期間たつとログアウト

みたいなのとかがある。 Authlete では OAuth / OIDC の Refresh Token も

  • 利用時に有効期限を伸ばすことで 「定期的にアクセスしてくるエンドユーザー(=リソースオーナー)は再度認証・認可をする必要がなくなり、一方、長期間使わないエンドユーザーは再アクセス時に認証・認可が必要となります。」
  • 有効期限は発行時のままにして 「アクセス頻度によらず、一定期間毎(リフレッシュトークンの有効期限が切れる毎)に、エンドユーザーは再度、認証・認可が必要となります。」

のどちらかを選べます。自由度高いですね。

トークン情報の更新 — Authlete ナレッジベース (Beta)

  • 発行済み Access Token の有効期限やScopeの値を更新するためのAPIがある
  • Access Token単位の指定、Client - ユーザーに関するトークンを指定できる

指定方法によって更新機能が異なり、発行済み Access Token を指定する場合は

  • 有効期限とスコープの更新ができる。
  • 任意の Key / Value の値をプロパティとして追加して、Authlete のDBに格納できる

ということで、任意の値を Access Token に紐づけられるとなれば、サーバレスというかBaaS的な使い方が広がりそうな気はします。

Client - ユーザーに関するトークンを指定については、"ユーザー単位での発行済トークン管理" に書いてあったやつですね。実行例は...と記載してありますが、この辺りはもうちょっと整理してあると読みやすそう。

そして、補足事項としてアクセストークンの単一化について記載してあります。 これは、ある Client / User に対して有効な Access Token を制限できるってことなので、リスクもないですね。

  • 発行済みで有効期限内であり、無効化されていない Access Token 全て
  • 最後に発行された Access Token のみ有効とし、過去に発行された Access Token は無効化される

という2種類の要件に対応できるというお話ですね。 これだけで1つのトピックとして成り立つぐらいの内容な気がしています。なんで補足なんだ。

認可タイプ

最適な OAuth 2.0 フローの選び方 — Authlete ナレッジベース (Beta)

Grant Type どれ使うか問題へのアドバイスでしょうかね。

基本的に、認可コードフロー(+ PKCE)の利用をご検討ください。どうしても認可コードフローが使えない場合、各種フローの性質をよく理解した上で、他の方法をご検討ください。

無難ですな。

スコープ

カスタムスコープの言語別説明文の登録 — Authlete ナレッジベース (Beta)

カスタムスコープの説明文を言語別に設定できるAPIがあるそうです。

クライアント管理

サービス管理者による開発者コンソールへのログイン — Authlete ナレッジベース (Beta)

開発者コンソールの話なので省略したいところだけど、API Key/Secret を API アクセス以外に使うのって...と思ったり思わなかったり。

シンプルにできるならそれでいいのかもしれないけど。

クライアント ID の別名化 — Authlete ナレッジベース (Beta)

  • Authlete には Client ID を払い出す機能がある
  • 既存の認可システムから Authlete に移行したい場合、既存の Client ID どうするの問題が発生する
  • Authlete では、Client ID のエイリアス機能を有効にすることで既存の Client ID を指定したままの移行が可能

ということですね。これはけっこう親切ですね。

ユーザーが認可したクライアントの管理に関する Authlete のポリシー — Authlete ナレッジベース (Beta)

  • (上の方でも出てきたけど)ユーザーが認可済み Client 一覧を取得できる
  • これは、"Access Token / Refresh Token が有効" な Client ではなく、"Access Token / Refresh Token がDBに存在する" Client だぞーん
  • なので、DBから消えたら出てこなくなる

というポリシーの宣言のようです。きっと裏ではユーザーIDでSELECTしてClientでまとめて...みたいな処理なのでしょう。

認証

OAuth 認証と OpenID Connect — Authlete ナレッジベース (Beta)

  • Access Token からプロフィールなどを引いた結果を用いて認証処理を行うみたいな、いわゆる OAuth 認証を Authlete を使って実現はできる
  • 様々な視点から考える必要があるので、SSOやID連携をするときは、OIDC の ID Token 使え

2012年の記事が参考文献として紹介されていますが、あれから今まで OAuth 認証だめ、OIDC 使えっていう啓蒙をするにふさわしい文献的なものはなかったっけなと振り返り中です。もう2018年も残り3ヶ月だぞ。

エラー処理

"fail" API を用いたエラーレスポンスの生成 — Authlete ナレッジベース (Beta)

  • Authorization Endpoint のエラーレスポンスの実装、サポートするパラメータが増えたりすると結構大変
  • Authlete にはそれやってくれるAPI がある
  • ROPC 使うとこ向けに、 Token Endpoint 用のものもある

確かに Response Code / Response Mode の値をサポートしようとしたらレスポンス生成部分だけで結構複雑な実装になりそうなので、このAPIは便利ですね。

クライアント認証

client_secret_jwt によるクライアント認証 — Authlete ナレッジベース (Beta)

ちなみに、例示のセクションを "テスト" と表現するのは微妙な気がしますね。

private_key_jwt によるクライアント認証 — Authlete ナレッジベース (Beta)

JWK用意するのだけちょっとめんどくさいかも?ライブラリに自動生成のスクリプトなりメソッドなりがあるともっと楽そうですね。 ちなみに、例示のセクショ(ry

UserInfo エンドポイント

Userinfo API におけるアクセストークン検証 — Authlete ナレッジベース (Beta)

Authlete の UserInfo APIAccess Token が有効かどうかを検証するので Introspection 叩かなくていいですよと。これ書くってことは、API仕様に書いといても見てくれないんでしょうかね。

あと、APIリファレンスだと /auth/userinfo (こっちがUserInfo取得?)と /auth/userinfo/issue (ID Token発行?)があるのでリンクは https://docs.authlete.com/#userinfo にでも貼っとくのが良さそう。

感想

Authlete というプロダクトが様々なところで使われるにあたり、仕様の範囲外の部分をどう設計/実装したのか、顧客もしくは内部から出てきた要件に対応するために考えたと思われる部分が詰め込まれていて興味深かったです。

この手のナレッジの表現方法はなかなか難しい印象がありますが、個人的には先に「このような要件があり」「自分たちはこう対応した」みたいな書き方だと読みやすいのかなと思いました。

そして、できれば「このような要件があり」の部分が 「OIDC Provider / OAuth 2.0 Server 実装の悩みどころ、実装あるある」 のように一般化されてどこかパブリックな所にまとめられていると良いのかも?と思ったりしました。

上で取り上げられているものでいうと

  • 使われていない Access Token を削除しちゃっていいのか
  • ハイブリッドフローで Implicit な認可レスポンスで返す Access Token と Authorization Code を受け取って返す Access Token で Scope 変えたい

とかが公開されていた場合、OIDC / OAuth の実装時に「これ考えないといけない」リストとしても使えますし、出来上がったプラットフォームや今回の Authlete のようなプロダクト以外にも、ライブラリの開発者などが後から「自分はこう対応した」というまさにナレッジの比較を行うこともできそうです。

この辺りはどこかで Authlete や他のプロダクトの方とお話ししてみたい所ですね(←何かへのフリ)。 ではまた。