msksgm’s blog

msksgm’s blog

Webエンジニアです.日々の勉強,読書,映画観賞,美術観賞の記録を載せます.

OAuthについてまとめてみる4 OpenIDConnectについて編

OAuth の勉強会のために「OAuth 徹底入門 セキュアな認可システムを適用するための原則と実践」 を読んでいます。

まとめた資料を記事にしました。
が、うまくまとまりませんでした、、、

今回は、OAuth の OpenID Connect について記述していきます。

OpenId Connect のざっくりとしたまとめ

ざくっくりとしたまとめ

OpenId Connect は OAuth 2.0 の仕様に認証の機能を拡張したもの。
OpeID Connect = OAuth 2.0 + ID トークン + UserInfo エンドポイント
だけど、OAuth 2.0 をそのまま認証につかってはいけない(トークンはクライアントのことをしらないし、クライアントはトークンについて理解しようとしてはいけない。後述)

用語について

OpenID Connect と OAuth2.0 の対応は以下。
ドメインが異なるから呼び方が違うのであって、どちらが正しいとか統一されるものではない。
OpenID Connect では右列、というだけ

OAuth OIDC
リソースオーナー エンドユーザー
クライアント リライング・パーティ
認可サーバー ID プロバイダ
リソースサーバー UserInfo エンドポイント

OAuth2.0 を使ったユーザー認証

OAuth2.0 は認可に関する決定をおこなう、委譲。
しかし、OAuth2.0 は認証されたエンドユーザーの承諾を得るために使われるので、認証のプロトコルと勘違いされやすい
その結果、OAuth2.0 を認証プロトコルに使おうとして、脆弱性が生まれることがある。

なぜ、OAuth2.0 は認証プロトコルではないのか?

認証とは、アプリケーションに誰が現在のユーザーであり、そのユーザーが現在そのアプリケーションを使っているのかどうかを伝えるもの。

OAuth は、アプリケーションにそのような情報を伝えない。
OAuth2.0 にとって重要なのは、トークンの問い合わせ、取得、トークンを使った API へのアクセス。
OAuth2.0 のクライアントは誰がアプリケーションにアクセスしたのか、さらには、そこにユーザーがいるのかさえまったく認識していない。

認証 vs 認可

OAuth2.0(認可)の委譲モデルは唯一無二のものである。

認証は、いくつかの鍵となる構成要素と工程が正しい方法でともに組み合わされることで、認証は正しく、そして安全に機能するようになる。

OAuth を使った認証プロトコルを構築した、FacebookTwitter、などのプロバイダもあれば、多くの異なるプロバイダをまたいで利用できる OpenID Connect のようなオープンスタンダートも存在する。

OAuth と認証プロトコルとの関連付け

OAuth を基盤とした認証プロトコルを構築するには、最初に、OAuth2.0 の異なる役割を持った構成要素を認証トランザクションにおける適切な箇所に配置する必要がある。
OAuth のトランザクションでは、リソース所有者がクライアントを認可し、そのクライアントが認可サーバーから受け取ったトークンを使って保護対象リソースにアクセスするようになっている。
認証のトランザクションでは、エンドユーザーはアイデンティティ・プロバイダ(Identity Provider: IdP)を使ってリライング・パーティー(Relying Party: RP)にログインする。
保護対象リソースからリライング・パーティーにアクセスしようとすると、セキュリティの境界がうまくできていない。
本来は OAuth のトークンがセキュリティドメインの境界を跨ぐはずが、直接保護対象リソースから取得してしまう。

そこで、クライアントがリライング・パーティーを RP となり、認可サーバーと保護対象リソースを組み合わせて、アイデンティティ・プロバイダへ IdP を担う。
アクセス・トークンと ID・トークンを使って認証イベント自体の情報が運ばれるようにする。

OAuth2.0 ではどのように認証を使うのか?

リソース所有者は認可サーバーの認可エンドポイントにて認証を行い、クライアントはトークン・エンドポイントにて認可サーバーにて認証をおこなう。

認可サーバーで認証するメリットは、1. エンドユーザーのクレデンシャルは OAuth2.0 のプロトコルを解して、クライアント(RP)に知られることがないこと、2. 実行時にユーザーの同意を得ることができること、3. ユーザーは自身のアイデンティティとともにほかに保護された API へのアクセス権を委譲できること。

認証に OAuth2.0 を使用する際に陥りやすい落とし穴

アクセス・トークンを認証の証明としてしまうこと

アクセス・トークンを認証の証明に使うと、クライアントがどのようトークンを取得したのかにかかわらず、クライアントはトークンの中身をみることができない。
本来なら、認証時にはクライアントはトークンからユーザー情報を取り出す必要があるため、役割が異なってしまう。

保護された API へアクセスできることを認証の証明としてしまうこと

アクセス・トークンと ID トークンの役割は切り分けないといけない。

アクセス・トークンのインジェクション

情報の受け手に対する制限の欠如

不正なユーザー情報のインジェクション

アイデンティティ・プロバイダごとに異なるプロトコル

OpenID Connect

OpenID Connect は 2014 年 2 月に OpenID Foundation によって公開されたオープン・スタンダート。OAuth2.0 を使ってユーザー認証を行うための相互運用可能な方法が定義されている。
このプロトコルは相互運用が可能になるように設計されているので、OpenID のクライアント・アプリケーションはひとつのプロトコルで多くのアイデンティティ・プロバイダ(IdP)とやり取りできるようになっている。

OpenID Connect は直接 OAuth2.0 上に構築されており、OAuth2.0 との互換性を保ったままになっている。

ID トーク

OpenID Connect の ID トークンは署名付き JWT(JSON Web Token)のこと。
通常の OAuth のアクセス・トークンとともにクライアント・アプリケーションに渡される。
アクセス・トークンとは違い、ID トークンはリライング・パーティー(RP)に対してのものであり、そのリライング・パーティーによって解析されることを意図したもの。

トークンのクレームには、ユーザーを表すもの(sub)、トークンを発行するアイデンティティ・プロバイダを表すもの(iss)、トークンがどのクライアントに対して作成されたのかを示す識別子を表すもの(aud)、有効期限などがふくまれる。

ID トークンはアイデンティティ・プロバイダの鍵を使って署名される。

UserInfo エンドポイント

アクセス・トークンを現在のユーザーに関する属性情報を提供する標準の保護対象リソースとして使うことができ、そのエンドポイントを UserInfo エンドポイントと呼ぶ。 この UserInfo エンドポイントからの結果に含まれるクレームには前述した認証プロセスで使われるものではないが、代わりにアプリケーション開発者にとって認証プロトコルをより意味のあるものにするためのんための認証されたユーザーに関する情報を提供する。

UserInfo エンドポイントは認可時に送られるアクセス・トークンとともに単純な GET か POST でおこなわれる。

UserInfo エンドポイントからのレスポンスはユーザーについてのクレームを持った JSON オブジェクトである。

動的なサーバー検出とクライアント登録

さまざまなクライアントやプロバイダによく使われるであろう API を定義することで、スケールしすいようになっている。

OpenID COnnect は検出プロトコル(Discovery Protocol)を定義しており、そのプロトコルはクライアントがどのように対象のアイデンティティ・プロバイダ(IdP)とやりとりをするのかについての情報を簡単に取り出せるようにしている。
工程は2段階になっており、1. クライアントは発行者の URL としてアイデンティティ・プロバイダの URL を見つけなければならない。そうすことで、検出用 URIHTTPS を介して取り出せるようにし、対象のユーザーのあどれすに関連している発行者を判別する。2. クライアントがサーバーについて知ることができれば、今度はサーバーがクライアントについて知る必要があある。そのため、OpenID Connect はクライアントを登録するためのプロトコルを定義しており、その登録プロトコルを通してクライアントを新しいアイデンティティ・プロバイダに登録できるようになっている。

まとめ

  • OAuth2.0 は認証プロトコルではないが、認証プロトコルを構築するために OAuth2.0 が使われることはある
  • 現在存在する多くの認証プロトコルは OAuth2.0 を使って構築されたものであり、昨今の Web でも使われるようになっている。そして、それらの多くは特定のプロバイダ専用のものとなっている
  • 認証プロトコルを扱う設計者は OAuth2.0 上で多くのよくある間違いを犯しがちである。これらの間違いは認証プロトコルを注意深く設計することで避けることが可能である
  • いくつかの重要な機能追加することで、OAuth2.0 の認可サーバーと保護対象リソースはアイデンティティ・プロバイダ(IdP)としてふるまうことができ、OAuth2.0 のクライアントはリライング・パーティー(RP)としてふるまうことができる
  • OpenID Connect は注意深く設計されたオープン・スタンダートであり、OAuth2.0 上に構築された認証プロトコルを提供する