1章
重要な用語
1.認証(Authentication)
ユーザ自身が何者であると主張しているかを検証するプロセス
ユーザ名が表すのはユーザが主張するアイデンティティであり、アプリケーション側は、ユーザの入力したパスワードが正しければ、本人であるとみなす
2.連合型認証(Federated Authentication)
ユーザアイデンティティの検証プロセスを外部サービスに依存しているアプリケーションのことをいう。
OpenIDなどが有名(OpenIDプロバイダのGoogleとかYahoo!とか)
3.認可(Authorization)
何らかの行為を行う際に、ユーザにその権限があるかどうかを検証するプロセス。
webアプリケーションは最初にログインしているIDを確認したあと、各操作に対するアクセスコントロールリストを参照して、そのアクセスが許可されている範囲のデータとサービスに対するものかを確認する。
4.委譲認可(Delegated Authorization)
他人やアプリケーションに自分に代わってアクションを実行してもらうためにアクセスを与えること。
ユーザはアプリケーションにアクセス権限を与え、ユーザのためにアクションを実行してもらう。ただし、アプリケーションが実行できるのは認可されたアクションのみ(scope的なノリ?)
5.ロール(Roles)
OAuthプロトコルに手順に登場する主な動作主体
-
リリースサーバ
OAuthによって保護されたユーザ取得リソースを保持、提供するサーバAPIプロバイダとかがこれを指す -
リリース所有者
アプリケーションのユーザ。リソースサーバが保持するジズからのデータに対するアクセスを許可する -
クライアント
リソース所有者の認可を受け、保護されたリソーに対して何らかのアクションを起こすよう所有者に代わってAPIにリクエストを行うアプリケーション(コンシューマのアプリ的な感じ) -
認可サーバ
リソース所有者の同意を得て、kライアンとにリソースサーバ上の保護されたリソースに対するアクセストークンを発行する。
MAC鍵
MAC鍵について
MAC鍵はhmac-sha-1 か hmac-sha256のアルゴリズムで生成されたものでなければいけない
署名が必須なOAuht対応APIへの接続では全てのAPIリクエストのAuthorizationヘッダにMAC署名が含まれていなければいなけない
MAC鍵の発行
OAuth認可サーバ自身で発行 access_tokenが認可サーバから返されるタイミングで毎回鍵も帰ってくる。
または、開発者がAPIproviderにアプリケーションを登録するときにMAC鍵がAPIリクエスト時以外の別プロセスで発行される場合もある。どんな方法で発行された鍵でも SSL/TLSチャネルによって機密に保たれていないといけない
APIリクエストの生成
署名が必須なOAuth対応APIへの接続では、全てのAPIリクエストのAuthorizationヘッダにMAC署名が含まれていないといけない。
署名を作成するにはリクエスト文字列(認証用乱数、HTTPメソッド、リクエストURI、ホスト名、ポート番号、ボディのハッシュ値など)を正規化して、暗号化しないといけない。
事前の登録
OAuthアプリケーションを登録するとクライアントクレデンシャルが発行される
-
クライアントID
リソースサーバと通信する際のclient_idの値として指定 -
クライアントシークレット
認可コードをアクセストークン、リフレッシュトークンと交換するときにclient_secretの値として指定
クライアントクレデンシャルは認可コードからアクセストークンへの交換や、アクセストークンの更新などを行う際に、それらのリクエストの信頼性を守るために使われる。
ベアラートークン
保護されたリソースへのアクセスで必要となるトークン値だけが含まれたアクセストークン
アクセストークン
OAuth2.0を利用するAPIの多くがリクエスト認可で必須としているのはベアラートークンのみ。ベアラートークンを使った認可では、APIリクエストを作成するときに暗号鍵のような追加情報を含める必要がない
OAuthを使う場合は全て同じアクセストークン取得して、APIリクエストを実行すること
アクセストークを取得したらそのトークンをAPIリクエストとともに送る。
最適な方法は
HTTPのAuthorizationヘッダを使うこと。
GET /unko/v1/product/@default/list HTTP/1.1
Host:www.unko.com
Authorization:Bearer unko.hash
authorizationヘッダを使うのが優れている理由は
-
ヘッダはプロキシサーバやwebサーバのアクセスログにログとして残ることがほぼない
-
ヘッダがキャッシュされることがほぼない
-
クライアントがリクエストを行うときに、ヘッダはブラウザキャッシュに残らない
OAuth2.0では他の方法も定義されているが、実装するかはプロバイダが決めること。
他の方法
1.クエリパラメータ
access_tokenをURLクエリパラメータに追加する方法。デバック時などは便利、クライアントサイドフローを使っている場合はJSONPのリクエスト形式のためこの方法が役に立つ
https://www.unko.com/unko/v1/product/@default/list?callback=outputTasks&access_token=unko.hash
こんな感じ
2.フォームエンコードされたボディーパラメータ
アプリケーションがAuthorizationヘッダを変更できない場合の手段。HTTPボディをHTTPボディにapplication/x-www-form-urlencodedコンテントタイプのパラメータを追加できる場合のみ使える
認可フロー
OAuth2.0プロトコルでは、認可を得るために使われる4つの基本的な「グラントタイプ」(認可供与方式)と、拡張方法が定義されている
1.認可コード
リソース所有者がデータへのアクセスを認可すると、その後、webアプリケーションにリダイレクトされるが、URLのクエリパラメータ軽視この認可コードが渡される。クライアントアプリケーションではこの認可コードをアクセストークンに交換する。交換の際にはclient_idとclient_secretが必須。また、リフレッシュトークンを使って APIへのアクセスを長期にわたって可能にすることができる。
2.インプリシットグラント(ブラウザベースのクライアントサイドアプリケーション用)
ブラウザで動作するクライアントサイドwebアプリケーション用に特化されている。リソース所有者がアプリケーションにアクセスすると即座に新しいアクセストークンが生成され、URLのハッシュフラグメントを使ってアプリケーションに送られる。jsなどを使ってハッシュフラグメントからアクセストークンを取得してAPIを実行。認可コードは不要だがリフレッシュトークンは使えない。
3.リソース所有者パスワードクレデンシャル
リソース所有者のユーザ名/パスワードがOAuhtアクセストークンと交換できる。APIプロバイダ自身が開発したアプリケーションなどの信用できるクライアントでのみ使われる。一度認証が終われば、あとはOAuthトークンだけおw保存しておけばオッケー。
4.クライアントクレデンシャル
アプリケーション自身の所有するリソースに対しアクセストークンを取得する場合、または、認可サーバとの事前のやりとりによって、すでに認可を得ている場合に使用する。特定のユーザではないので、ストレージサービスやデータベースなどのAPIアクセスが必要な場合に適している。
以下は追加的なフロー
5.デバイスプロファイル
入力方法に制限あがあるデバイスでOAuthを使用するために作られたもの。
Facebookhがフローの実例を紹介してるよ☆
http://oauth-device-demo.appspot.com/
6.SAMLベアラーアサーションプロファイル
SAML2.9アサーションをOAuthアクセストークンに交換できる。