- lifeisegg
- Feb 21, 2018
- Tags
OAuth 2.0
JWTの仕組み
OAuth 2.0
※認証ではなく、認可
OAuthとは、「認可情報の委譲」のための仕様
- あらかじめ信頼関係を構築したサービス間で
- ユーザの同意のもとに
- セキュアにユーザの権限を受け渡しする
サービス間で認可情報を受け渡せると,あるサービスがユーザの認可のもとで別のサービスの管理する情報の取得/追加/更新/削除などを行えるようになります。OAuthに対応したサービスでは,ユーザが外部サービスにパスワードを教えることなく,認可情報の委譲が可能です。また認可情報の適用範囲を指定したり,有効期限を設定することができるため,ユーザが外部サービスにすべての権限を渡すこと無く,自分が利用したいサービスに最低限必要な権限のみを委譲することができます。そのためBasic認証と比べて柔軟かつセキュアな運用が可能です。
OAuth 2.0のプロトコルフロー
- A.まずクライアントがリソースオーナーに認可要求(Authorization Request)を出す。図ではクライアントがリソースオーナーに直接要求を出しているが、認可サーバー経由で間接的に要求する事がのぞましい
- B.リソースオーナーは認可要求を許諾する旨の返答として認可グラントをクライアントに送る。これも認可サーバー経由で行う事がのぞましい
- C.クライアントは認可サーバーに認可グラントを送ることでアクセストークンを要求
- D.認可サーバーはクライアントの認証と認可グラントの正当性の検証を行い、問題なければアクセストークンを発行
- E.クライアントはアクセストークンにより認証を受けることで、保護されたリソースへのアクセスをリクエスト
- F.アクセストークンが正当なら、クライアントのリクエストを受け入れる
認可グラントにはその発行の方法
- 認可コード
クライアントはリソースオーナーを認可サーバにリダイレクトし、認可サーバはリソースオーナーを認証した上で認可コード型の認可グラントを発行する。 - インプリシット
スクリプト言語を使用してブラウザ上で実行されるクライアント向けに認可コードを最適化したもの - リソースオーナーパスワードクレデンシャル
ユーザ名とパスワードのペアのような、リソースサーバーへのフルアクセスを許す情報をリソースオーナーパスワードクレデンシャルと呼び、この情報を直接アクセストークンとして得る。 - クライアントクレデンシャル
認可範囲がクライアントの管理下にある保護されたリソース, もしくはあらかじめ認可サーバーとの間で調整済の保護されたリソースに制限されている場合に用いる。
JWT = JSON Web Token
JSONを使ったコンパクトでurl-safeなクレームの表現方法であり、OAuth2やOpenID Connectなんかで使われます。
JWS = JSON Web Signature
構成
- 1 番目には、Key の種類、Key の ID (X.509 Thumprint) など証明書 (Key) に関する基本情報が含まれています
(これは、証明書が入れ替わるタイミングなどを除き、概ね 固定の値です) - 2 番目には、Claim 情報が入っています。後述しますが、表示名 (氏名) やメールアドレスなどの基本情報と、有効期限や付与された scope (access token の場合) などセキュリティ情報を含んでいます
- 3 番目には、デジタル署名 (digital signature) の byte code が入っています。
Header
JWTの基本情報が記載されている
{
"typ": "JWT",
"alg": "RS256",
"x5t": "SSQdhI1xxxxxxxxxxxxxxxxxxx",
"kid": "SSQdhI1xxxxxxxxxxxxxxxxxxx"
}
パラメーター名 | 説明 |
---|---|
typ | JWS 自身のメディアタイプ |
alg | アルゴリズム、署名で使用されるもの |
x5t | X.509 証明書 SHA-1 Thumbprint |
kid | キー ID |
他にjku(JWK セット URL)、jwk(JSON Web キー)、x5u(X.509 URL)、x5c(X.509 証明書チェーン)、x5t#S256(X.509 証明書 SHA-256 Thumbprint)、cty(ペイロードのメディアタイプ)、crit(必須パラメーター群指定)があるがこのPJでは使用しなし。
Payload
JWTの有効期間、クレーム、ユーザー情報などが記載されている
{
"aud": "xyxz-xyxz-xyxz-xyxz-xyxzxyxzxyxz",
"iss": "https://sts.windows.net/xxxxx-xxxx-xxxx-xxxx-xxxxx/",
"iat": 1518766096,
"nbf": 1518766096,
"exp": 1518769996,
"aio": "xyzxyz/c/wuX/xyzxyzxyzxyz/xyzxyzxyzxyzxyzxyzxyzxyz",
"amr": [
"wia"
],
"family_name": "fName",
"given_name": "gName",
"ipaddr": "xxx.xxx.xxx.xxx",
"name": "fName gName",
"nonce": "xxxxyyy-wxyz-wxyz-wxyz-xyzxyzxyzxyz",
"oid": "xxxxyyy-wxyz-wxyz-wxyz-xyzxyzxyzxyz",
"onprem_sid": "S-1-5-21-xxxxxx-xxxxxxxx-xxxxxxx-xxxxxxx",
"sub": "kBIE6ZBOnnbOI-7r70Y-TkcFefl4mc-TH00AM1OOyzQ",
"tid": "xxxxyyy-wxyz-wxyz-wxyz-xyzxyzxyzxyz",
"unique_name": "fname@sample.com",
"upn": "fname@sample.com",
"uti": "xyzxyzxyzxyzxyzxyzxyz",
"ver": "1.0"
}
Signature
YyDuZVG3ORaRwEj1wHywCsYZMP6d6JcawkVXodzJTu_Wu1y2YxzlA4-XNdOGIzVMKiskroORaRwEj1wHywCORaRwEj1wHywCjIqdSgsg_m9yHNUZ6GK7l78nDBnCSci4BfV3OfcWjTis30QggkiCqfTp3ubaymyf8h2kVUPsBQcxWxjCiwOdPBG4W64m95tJORaRwEj1wHywCORaRwEj1wHywCBsii4JD5rlnlJjEkSr_AT4rF_y51ORaRwEj1wHywCE28UhjgzYtORaRwEj1wHywCORaRwEj1wHywCGo1qhVkzLMSbpxJHqHY_ORaRwEj1wHywCHOOhYORaRwEj1wHywCjtDg-escGmkinw
エンコード済のJWSヘッダとエンコード済のJWSペイロードをRSASSA-PKCS1-v1_5 using SHA-256アルゴリズムで署名したもの
クレーム
JSONオブジェクトで表現され、クレームセット内のクレームは一意でなければならない。
ヘッダと同様に、クレーム名が重複したJWTは拒否するか、ECMAScript 5.1 の節 15.12 (JSON オブジェクト) で定義されているとおり語彙的に最後の重複メンバ名だけを返却する JSON パーサを利用しなければならない。
JWTのクレームには予約済みクレーム名とパブリッククレーム名、プライベートクレーム名の3つのクラスが定義されている。
パラメーター名 | 説明 |
---|---|
iss | JWT発行者の識別子。 |
sub | JWT発行者から払い出されたユーザ識別子。 |
aud | JWTを利用することが想定された主体の識別子。 オーディエンスクレームの値に自身の識別子が含まれていることを確認し、含まれない場合は、そのJWTの処理を拒否しなければならない。 |
exp | JWTの有効期限を示す。有効期限以降のJWTを処理してはならない。 expクレームを処理する際には、現在時刻がexpで記載されている時刻より前であることを確認しなければならない。 |
nbf | JWTが有効になる日時を示す。これより前にJWTを処理してはならない。 nbfクレームを処理する際には、現在時刻がnbfの時刻より後であることを確認しなければならない。 |
iat | JWTを発行した時刻を示す。 |
jti | JWTのための一意な識別子。 JWTがリプレイされることを防ぐことに利用することができる。 重複確立が無視できるほど十分に低いことを保証できる方法で割り当てなければならない。 |
typ | typヘッダパラメータと同じ値空間および同じ規則が適用される。 |
パブリッククレーム
JWTの利用者によって自由に定義できるが、衝突をさけるために、IANA JSON Web Token Claim Registry に登録するか、耐衝突性を持つ名前空間を含むパブリック名にすべきである。
プライベートクレーム
JWTの作成者と利用者の合意のものとで、予約済みでもパブリッククレーム名でもないプライベートクレーム名を用いてもよい。 ただし、衝突の可能性があるため、慎重に使用する必要がある。
参考
- https://tsmatz.wordpress.com/2016/03/08/azure-ad-msa-v2-endpoint-validate-id_token/
- https://openid-foundation-japan.github.io/draft-ietf-oauth-json-web-token-11.ja.html
- https://hiyosi.tumblr.com/post/70073770678/jwt%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E7%B0%A1%E5%8D%98%E3%81%AB%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E3%81%BF%E3%81%9F
1. 認可コードフロー
2. インプリシットフロー
3. リソースオーナー・パスワード・クレデンシャルズフロー
4. クライアント・クレデンシャルズフロー
5. リフレッシュトークンフロー
まとめ
フロー | 認可エンドポイント | トークンエンドポイント | 特徴 |
---|---|---|---|
認可コード | 使う | 使う | 短命の認可コードの発行を受け、トークンエンドポイントでアクセストークンと交換する。 |
インプリシット | 使う | 使わない | 認可エンドポイントから直接アクセストークンの発行を受ける。 |
リソースオーナー・パスワード・クレデンシャルズ | 使わない | 使う | ユーザーの ID とパスワードをクライアントに渡す。 |
クライアント・クレデンシャルズ | 使わない | 使う | クライアントアプリの認証のみでアクセストークンの発行を受ける。 |
リフレッシュトークン | 使わない | 使う | リフレッシュトークンを提示してアクセストークンの再発行を受ける。 |
参考
- https://authlete.com
- https://murashun.jp/blog/20150920-01.html
- https://qiita.com/TakahikoKawasaki/items/200951e5b5929f840a1f
- https://qiita.com/TakahikoKawasaki/items/4ee9b55db9f7ef352b47
Comments
Add your comment