OAuth 2.0

JWTの仕組み

OAuth 2.0

   

※認証ではなく、認可

OAuthとは、「認可情報の委譲」のための仕様

  • あらかじめ信頼関係を構築したサービス間で
  • ユーザの同意のもとに
  • セキュアにユーザの権限を受け渡しする

サービス間で認可情報を受け渡せると,あるサービスがユーザの認可のもとで別のサービスの管理する情報の取得/追加/更新/削除などを行えるようになります。OAuthに対応したサービスでは,ユーザが外部サービスにパスワードを教えることなく,認可情報の委譲が可能です。また認可情報の適用範囲を指定したり,有効期限を設定することができるため,ユーザが外部サービスにすべての権限を渡すこと無く,自分が利用したいサービスに最低限必要な権限のみを委譲することができます。そのためBasic認証と比べて柔軟かつセキュアな運用が可能です。

OAuth 2.0のプロトコルフロー

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

構成

JWT 構成
  • JWT (id token など) は dot (.) 区切りの 3 つのトークン文字列で構成されています
  • 各トークン文字列は、RFC 4648 による変形 Base 64 により Encode されています
  • 各トークンを Decode すると、下記の内容が記載されています
    • 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"
    }
    
    
    パラメーター名説明
    typJWS 自身のメディアタイプ
    algアルゴリズム、署名で使用されるもの
    x5tX.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つのクラスが定義されている。

    パラメーター名説明
    issJWT発行者の識別子。
    subJWT発行者から払い出されたユーザ識別子。
    audJWTを利用することが想定された主体の識別子。
    オーディエンスクレームの値に自身の識別子が含まれていることを確認し、含まれない場合は、そのJWTの処理を拒否しなければならない。
    expJWTの有効期限を示す。有効期限以降のJWTを処理してはならない。
    expクレームを処理する際には、現在時刻がexpで記載されている時刻より前であることを確認しなければならない。
    nbfJWTが有効になる日時を示す。これより前にJWTを処理してはならない。
    nbfクレームを処理する際には、現在時刻がnbfの時刻より後であることを確認しなければならない。
    iatJWTを発行した時刻を示す。
    jtiJWTのための一意な識別子。
    JWTがリプレイされることを防ぐことに利用することができる。
    重複確立が無視できるほど十分に低いことを保証できる方法で割り当てなければならない。
    typtypヘッダパラメータと同じ値空間および同じ規則が適用される。

    パブリッククレーム

    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

    記事のサブ画像




    コメント

    コメントを追加

    user-symbol

    Stay in touch

    ビジネスおよび開発者向けの実用的な最新情報をご希望ですか?

    ソースコードプロジェクトに対するPieceXコミュニティのニーズについてご提供します。

    PieceXの最新の無料コミュニティコードプロジェクトをいち早くお知らせします。