クライアント登録

クライアント登録

[10] クライアントcredentials (client credentials) は、 OAuthクライアントを識別、認証するための credentials です。

仕様書

クライアントの登録

[5] OAuth 1.0 では、認証された要求の作成に先立ってクライアントとの間でクライアントcredentials を準備しておく必要があります >>3

[24] OAuth 2.0 では、利用に先立ってクライアント認可鯖に自身を登録することになっています >>20認可鯖は、登録されたクライアントクライアント識別子を発行します。

[27] しかしその具体的な方法は、 OAuth 1.0 >>3OAuth 2.0 >>20 も仕様の範囲外としています。

[6] 一般的には、当該Webアプリケーションの管理画面等でクライアントを登録することで、 クライアントcredentialsが生成されるという形が採られています。
[25] しかしクライアント認可鯖が直接やり取りして登録する必要はなく、 自己または第三者の発行する表明に基づいたり、 信頼できる通信路によるクライアント発見法を用いたりしても構いません。 >>20

[92] OAuth 2.0 の追加仕様である RFC 7591 >>90RFC 7592 >>91 では、 Web API によりクライアントの登録と管理を行わせるための方法が規定されています。

[93] しかし新しい仕様であり、ほとんど実装は見かけません。今後普及するかどうかは未知数です。

[26] OAuth 2.0 クライアントの登録においては、 クライアントの開発者が次の情報を提供しなければなりません >>21

[48] OAuth 1.0 は未登録のクライアントの利用に言及していませんでした。 OAuth 2.0 は未登録のクライアントの利用を排除していませんが、 OAuth 2.0 仕様の範囲外ともしています >>20

[69] GoogleOAuth 1.0 時代に consumer keyconsumer secret を共に anonymous として oauth_signature_method=HMAC-SHA1 を使う >>68 ことで、未登録のクライアントの利用を認めていました。

[35] 更に OAuth 2.0クライアント型機密クライアントに対してトークンエンドポイントクライアント認証を求めており、またクライアント型公開クライアントクライアント認証することを認めています。従って認可鯖およびクライアントはそのための情報も保持する必要があります。

[36] 資源所有者合言葉credentialsは、他の承諾型よりも限定的に用いるべきだとされています。 従って認可鯖は、クライアント資源所有者合言葉credentials を利用できるかどうかのフラグも保持する必要があります。

[67] OpenID Connectクライアント登録のための API の規定を含んでいます。

[89] Herokuクライアント登録API を提供しています >>88

OAuth 1.0 クライアント credentials

[4] クライアントcredentialsは、 固有識別子 (unique identifier) と、 共有秘密 (shared-secret) (クライアント共有秘密 (client shared-secret) >>9) か RSA鍵組 (RSA key pair) (RSA公開鍵RSA秘密鍵) によって構成されます >>3

[2] 元はクライアント識別子のことを consumer keyクライアント共有秘密のことを consumer secret と呼んでいました >>1

[52] クライアント識別子は、認証された要求においてクライアントを識別するために oauth_consumer_key 引数で使います。

[32] クライアント共有秘密は、 oauth_signature=HMAC-SHA1oauth_signature=PLAINTEXT で使います。 RSA鍵は、 oauth_sianature=RSA-SHA1 で使います。

[53] 共有秘密と鍵の組の両方を保持する必要はありません。 用いない署名方式のものは不要です。

[54] クライアント識別子は、秘密ではありません。

[12] 共有秘密RSA秘密鍵は、クライアントが秘密に保持しておく必要があります。 共有秘密署名の計算のために保持しておく必要があります。

oauth_signature=PLAINTEXT では共有秘密要求の一部として転送されます。

[13] クライアントネイティブアプリケーション実行ファイルが配布される場合のように、 クライアントcredentialsを攻撃者が入手できてしまう場合もあります。 クライアント識別 (identity) 検証 (verify) クライアントcredentialsだけでなく、 可能ならIPアドレスその他の要素も考慮するべき (should) です。 >>11

[14] 実行ファイルが配布されるパターンで IPアドレスをチェックしても何の意味も無い気がしますが・・・。 不特定多数に配布されるネイティブアプリケーションクライアントとして OAuth 1.0 Web API を利用する場合にはクライアントcredentialsは意味を持たないものとして諦める以外に有効な策は無さそうです。
[16] 資源所有者認可資源所有者に明示的に確認せずにトークンcredentials が発行されるような実装になっていると、公開されているクライアントcredentials を使って第三者がトークンcredentialsを取得できてしまい、特に危険です >>15。 (資源所有者認可も参照。)
[33] OAuth 2.0 ではこの性質をクライアント型と呼んで分類しており、 クライアントcredentialsを秘匿できない場合も考慮されています。

OAuth 2.0 クライアント識別子

[31] 認可鯖は、登録されたクライアントに対してクライアント識別子 (client identifier) を発行します。 クライアント識別子は、クライアントが提供した登録情報を表す、 認可鯖について固有の文字列です。 >>20

[43] 使用できる文字は、client_id 引数の構文上の制約のため、 印字可能ASCII文字に限られます。

[22] クライアント識別子は、秘密ではありません。これ単独でクライアント認証に使ってはなりません>>20

[23] クライアント識別子の長さは OAuth 仕様としては未定義となっています。 クライアントは仮定を置くべきではありません。 認可鯖は長さを文書化するべきです>>20

[81] SurveyMonkeyclient_id利用者名とし、 client_secretapi_keyが発行した値としています >>80api_key は公開の値なので、広義のクライアント識別子を構成するものと言えますが、なぜ client_id と2つ指定させているのかは不明です。

[87] GitHub認可に関する問い合わせの APIclient_idclient_secret基本認証利用者名合言葉として使っています >>86

OAuth 2.0 クライアント認証

[65] トークンエンドポイントでは、クライアント識別子credentials を使ったクライアント認証が行われます。

OAuth 2.0 クライアント credentials 承諾型

[18] OAuth 2.0 承諾型としてのクライアントcredentialsは、 クライアントcredentials (やその他の形のクライアント認証) を認可承諾として使うものです >>17, >>61

[19]承諾型は、認可適用範囲 (scope) がクライアントの制御下にある被保護資源に限定される時 (クライアント資源所有者でもある時) や、 他の資源所有者の制御下にある被保護資源であっても認可鯖との間で (OAuth の仕様外の何らかの方法で) 事前の取り決めがある時に使うことができます >>17, >>61

[62]承諾型は、クライアント型機密の場合以外は使ってはなりません >>61

[63] クライアントはまず認可鯖トークンエンドポイントアクセストークンの要求を送信します。 認可鯖クライアント認証を行ってから、アクセストークンを発行します。 >>61

C
クライアント
S
認可鯖
C -> S
トークンエンドポイントアクセストークンを要求
S -> C
アクセストークンを発行

[72] Azure が実装しています >>71。事前に登録した ID と鍵の組を使うようです。

[74] Twitter が実装しています >>73consumer keyconsumer secret を使うようです。

[76] Spotify が実装しています >>75

[78] reddit は「Application Only OAuth」として gran_type=client_credentialsgrant_type=https://oauth.reddit.com/grants/installed_client を利用しています。前者は機密クライアントとしてアクセスする場合に、 後者は公開クライアントとしてアクセスする場合並びに 「ログアウト状態の利用者」としてアクセスする場合に使います。 >>77

[85] GitHub基本認証を使って OAuth アクセストークンを取得する API >>84 は本承諾型とよく似ていますが、基本認証により資源所有者の認証を行い、 payload bodyclient_idclient_secret を使ってクライアントの認証を行うものとなっています。 トークンエンドポイントとは異なるエンドポイントで独自の引数を使う他、 応答の形式も本承諾型とは異なっています。

[70] GoogleOAuth 1.0 の拡張である 2-legged OAuth を使うと、 Google Apps の (特定の利用者に限定せず) ドメイン全体のアクセスを認めることができました。 本承諾型はこのような用途に使えるものと思われます。ただし Google は現在 Google Appsドメイン全体のアクセスには urn:ietf:params:oauth:grant-type:jwt-bearer を使っているようです。

[83] foursquare は本承諾型のような用途で client_idclient_secretURL query に指定する方法を採用しています >>82

oauth_consumer_key 引数 (OAuth 1.0)

[8] oauth_consumer_key は、認証された要求クライアントcredentials識別子 (consumer key) を表す >>7 引数です。

client_id 引数 (OAuth 2.0)

[49] client_id 引数は、 クライアント認証クライアント識別子を表します >>34クライアント認証を行う場合、この引数必須です >>34

[40] この引数の値は、0個以上の印字可能ASCII文字の列です >>39

[58] 認可エンドポイント認可符号アクセストークンを取得する場合、 この引数は指定しなければなりません >>57, >>60。 指定されない場合や非妥当な場合、資源所有者誤りを知らせるべきです >>59

[56] client_id 引数認証しない場合でもトークンエンドポイントへの要求 >>55 で指定できる場合、指定しなければならない場合があります。 認可鯖は、トークンエンドポイントで適宜認証および検査しなければなりません。

client_secret 引数 (OAuth 2.0)

[50] client_secret 引数は、 クライアント認証クライアント秘密を表します >>34。 この引数は、値が空文字列なら省略できます >>34

[42] この引数の値は、0個以上の印字可能ASCII文字の列です >>41

[38] クライアントcredentialsは、平文で送信してはなりません >>37

grant_type=client_credentials

[64] OAuth 2.0 トークンエンドポイントgrant_type 引数の値 client_credentials >>41 は、クライアントcredentials承諾型を表します。

セキュリティー

[44] クライアントが秘密の値を保持する場合、ソースコードであれバイナリであれ、 それが公開されていると、 (暗号化されていたとしても原理的には) クライアントを配布された第三者がその値を知ることができてしまいますから、 注意が必要です >>45, >>66。またクライアントに埋め込まれて配布される場合、 それを revoke することも (すべての利用者が使えなくなってしまうので) 難しくなり、好ましくありません >>66

[46] OAuth 1.0 ではクライアントcredentialsが必須なので、 秘密の値が漏れることを承知の上でネイティブアプリケーションが配布されていたりします。 OAuth 2.0クライアント型を設け、公開クライアントクライアント認証を行わないことを認めています。

[47] また、クライアントの開発者ごとにcredentialsを発行するのではなく、 クライアント利用者ごとに発行することでこれを回避する場合もあります。 その場合でも、環境によっては第三者 (によるアプリケーション) がクライアントストレージなどにアクセスして秘密の値を入手することが可能かもしれず、注意が必要です >>45

[51] 例えば伝統的なデスクトップOSでは同じ計算機上で動作する他のソフトウェアファイルシステム上の設定ファイルに容易にアクセスできるかもしれません。
[94] Bitbucket API () <https://developer.atlassian.com/bitbucket/api/2/reference/meta/authentication>

Somewhat like our existing "2-LO" flow for OAuth 1. Obtain an access token that represents not an end user, but the owner of the client/consumer:

$ curl -X POST -u "client_id:secret" \

https://bitbucket.org/site/oauth2/access_token \

-d grant_type=client_credentials