OAuth(オー・オース)とは、APIの認証を委譲するオープンプロトコルである。
OpenIDでは満足できない! 俺はもっと! マッシュアップしたいんだ! 俺は! Oh, ASS!
そんなわけで、外部サイトやソフトウェアとのAPIの認可する手段として新たに公表されたものがこれらしい。
一言で言えば、OpenIDの進化形と考えれば良いのではなかろうか。
OAuthを採用したサイトと、外部サイトやソフトウェアとのAPIの認可を与えると言う仕組み。
その際には、発行されたトークン(暗号化された文字列キー)で認証を行い、APIの認可をする。
これにより、外部サイトやソフトウェアなどからのログイン認証や、メッセージの表示や送信などの制御ができる。
だが、それを可能とするのが長所であり短所でもあったりする。
OAuth認証後にユーザーの知らない間になんらかの動作をする危険が危ないことが問題になっている。
というか、OAuthは本来認可のために用いるプロトコルなので、OpenIDとは用途が全く異なる(あちらは認証のために用いる)。よく言われるたとえは「OAuthは合鍵、OpenIDは身分証」というものであり、これを聞けば認証にOAuthを使うのがいかにおかしいかがわかるだろう。
だが、それが横行した結果、最終的に出てきたのがOAuth 2.0とOpenID Connectである。手っ取り早い話がOpenIDの仕組みをOAuthに取り込んでしまったのだ(要するに身分証の発行権限を合鍵に与えたということ)。
というわけで、OAuth 2.0とOpenID Connectを採用している場合は、両者を同時に取り扱って構わない。ただし、それぞれで使うトークンが異なる点には注意。
OAuth 1a(Twitterなどで採用)とOAuth 2.0(Googleなどで採用)では全くフローが異なる。以下、それぞれのフローを順番に見ていくことにする。
なお、サーバとプロバイダとの間のアクセスには、コンシューマキーとコンシューマシークレットというのが必要になる。コンシューマシークレットは絶対に秘密にしておかなければならないものである。
アプリの場合、サーバはアプリそのものが担い、コールバックURLもアプリ呼び出し用のURLになる。アプリは4でブラウザを起動して許可を求め、許可を選んだらアプリに戻って残りの処理を行うことになる。
一方、ブラウザの場合、サーバは別に必要であるが、4で表示する際には同じウィンドウで開けばよい。
フローはコード・暗黙的・パスワード・クライアントの4種類がある。OAuth 2.0はRFC6749にて定められている。
主な使い分けは以下の通り。
クライアントIDは公開して構わない情報である。一方、クライアントシークレットは秘密にしておかなければならない情報である。
コードフローの場合、認可URLにアクセスする際、response_typeにはcodeを指定する(OpenID Connectを行う場合もcodeである。codeとtoken/id_tokenを一緒に指定するとハイブリッドフローになり、暗黙的フローとコードフローが混じってしまうため面倒)。そのほかに必要なのはクライアントID・認可後のリダイレクト先URI・アクセスするリソースの範囲(OpenID Connectの場合ここにopenidが入っている必要がある)・リプレイ攻撃を防ぐためのトークンである。
ここで認可をもらうと、リダイレクトURIにはコードとリプレイ攻撃防止用のトークンが渡される。この後、トークンエンドポイントにクライアントID・クライアントシークレット・リダイレクトURIとともに、grant_typeにauthorization_codeを渡す。
これにより、アクセストークンとおよびアクセストークンの有効期限(もしOpenID Connectを要求しているならば同時にIDトークンも)、および許可されているならリフレッシュトークンをもらうことができる。IDトークンの説明はこの後、暗黙的フローと一緒に説明する。以後、リソースへのアクセスにはアクセストークンを用いる。
一方、リフレッシュトークンは、アクセストークンの有効期限が切れたとき、アクセストークンと引き換えが可能なトークンである。
暗黙的フローの場合、認可URLにアクセスする際、response_typeにはtokenを指定する(なお、OpenID Connectだけを行う場合はid_token、両方を行う場合はtokenとid_tokenの両方を指定する)。残りのパラメータはコードフローと同じである。
ここで認可をもらうと、リダイレクトURIにアクセストークンと有効期限と先ほどのリプレイ攻撃防止用のトークンが渡される(OpenID Connectだけの場合はIDトークンのみ、両方を指定した場合はアクセストークンとIDトークンの両方が渡される)。各トークンの使い道はコードフローと同様。
ページ完結型の場合は、このフローを用いるのがベストである。アプリも、クラックされるリスクを考慮するとこちらを用いるのが通例。
パスワードフローの場合、トークンエンドポイントにクライアントID・クライアントシークレット・ユーザ名・パスワード・スコープを渡すとともに、grant_typeにpasswordを渡す。これによりアクセストークン(および許可されているならばリフレッシュトークン)をもらうことができる。
ユーザにプラットフォームのユーザ名とパスワードを入力してもらうという構造的問題から、一般的なアプリケーションで用いることはなく、一部プラットフォームのBotなどで用いられる程度である。
クライアントフローの場合、トークンエンドポイントにクライアントID・クライアントシークレットを渡すとともに、grant_typeにclient_credentialsを渡す。これによりアクセストークンをもらうことができる。
そもそも、ユーザが一切介在しないことからわかる通り、ユーザに関するリソースへのアクセスは一切不可。実際のところ使用例はあまり多くなく、Facebookでのユーザのユーザアクセストークンのデバッグなどで用いられる程度である(発行されたユーザアクセストークンの管理はクライアント側の責務なので、クライアントフローを用いる)。
IDトークンとは、認証されたユーザが何者であるかなどの情報が入ったトークンである。このIDトークンはJSON Web Tokenの形式になっており、ピリオドで区切られた以下の3つの情報から構成される。
署名の仕組みを用いて、署名を行い、それを末尾に追加する。それぞれのコンポーネントはBase64を使って符号化されている。
署名の仕組みと署名に関しては割愛するとして、クレームには何が入っているのか。
まず、どのプロバイダが作ったのかをissで確認する。その後、expに指定された有効期限が到来してないかを確認したら、署名の検証を行う。問題がなければ、audで自分宛かどうかを確認し、subでユーザの識別子を取得するとともに、その他の情報と合わせてユーザ情報の登録や更新などを行う。
など。(これ以上追加してもキリがない)
掲示板
提供: インドコアラ
提供: カレーの王子
提供: 寺本
提供: はづき
提供: ゆんなの
急上昇ワード改
最終更新:2025/04/14(月) 09:00
最終更新:2025/04/14(月) 08:00
ウォッチリストに追加しました!
すでにウォッチリストに
入っています。
追加に失敗しました。
ほめた!
ほめるを取消しました。
ほめるに失敗しました。
ほめるの取消しに失敗しました。