マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

Finalを参照して記述。

  • OpenID Connectの用途としては、「認証の仕様である」と言ってイイ。
  • しかし技術的には、「IDトークン発行のための仕様」と考えたほうがイイ。
  • JWT
    • このIDトークンと呼ばれるトークンJWTアサーションを使用している。
      (JSON Serializationではなく、Compact Serializationを用いる。)
    • 従って、JWTの生成(署名)・検証の仕組みについては、JWTを参照のこと。
    • このページでは、OpenID Connectの認証用のJWTアサーションの
      トークン・プロファイル(オプション仕様)についてを説明する。

特徴

モジュラーデザイン

ユースケースに対応するため、

  • 複数の仕様から成り立っており、
  • それらをモジュール的に組み合わせることで

多様な環境をサポートできる。

プロトコル概要

ざっくり、リクエスト→認証・認可→ユーザ情報を取得。

+--------+                                   +--------+
|        |                                   |        |
|        |---------(1) AuthN Request-------->|        |
|        |                                   |        |
|        |  +--------+                       |        |
|        |  |        |                       |        |
|        |  |  End-  |<--(2) AuthN & AuthZ-->|        |
|        |  |  User  |                       |        |
|   RP   |  |        |                       |   OP   |
|        |  +--------+                       |        |
|        |                                   |        |
|        |<--------(3) AuthN Response--------|        |
|        |                                   |        |
|        |---------(4) UserInfo Request----->|        |
|        |                                   |        |
|        |<--------(5) UserInfo Response-----|        |
|        |                                   |        |
+--------+                                   +--------+
Client(RP)                                IdP/STS(OP)

OAuth 2.0への認証拡張

OAuth 2.0との違いは、認証拡張機能が追加実装された点にある。

  • OAuth 2.0では
    • 認証機能(「認証Endpointからユーザー属性クレーム群を取得する」)の仕様が無かった。
    • このため、この部分の拡張仕様(認証Endpoint)に方言があり、実装上問題だった。
  • 参考

仕様の柱

フロー

OAuth 2.0に認証結果とプロフィールの受渡し機能を追加。

IDトークン

追加のエンドポイント

フロー

概要

フロー選択の指針

特定のコンテキストにおいてどのフローを選択すればよいかの指針

#PropertyAuthorization Code FlowImplicit FlowHybrid Flow
1全てのトークンは Authorization Endpoint から返却されるnoyesno
2全てのトークンは Token Endpoint から返却されるyesnono
3トークンが User Agent に渡らないyesnono
4Client 認証が可能であるyesnoyes
5Refresh Token を利用できるyesnoyes
6通信が1往復だけであるnoyesno
7殆どの通信がサーバ間通信であるyesnovaries

response_type 値とフローの対応

メッセージのシリアライズ方法

  • GETリクエスト:
    application/x-www-form-urlencoded (Query String Serialization)
  • POSTリクエスト:
    application/x-www-form-urlencoded (Form Serialization)
  • JSON
    定義されていないが、以下で利用されるモノと思われる。
  • POSTリクエスト:
    Request body
  • GET, POSTレスポンス:
    Response body
  • JWT化すれば以下のリクエストで使用可
  • GETリクエスト:
    Query String Serialization
  • POSTリクエスト:
    Form Serialization

リクエスト・パラメタの追加・変更

  • OPTIONAL ---> REQUIRED
    • redirect_uri
    • scope
      scope="* openid *"は必須。
      • OpenID Connect リクエストは scope に openid を含まねばならない (MUST).
      • openid scope 値が存在しない場合の挙動は定義しない.
      • 他の scope 値が存在していても良い (MAY).
  • claims系
  • request
    Requestオブジェクト(JWT)
  • request_uri
    Requestオブジェクト(JWT)を返すエンドポイントのUrl(https)
  • display (OPTIONAL)
    Authorization Server は認証/認可の同意 UI を、
    • page
      User Agent の全画面に表示すべき(既定値)
    • popup
      User Agent のポップアップウィンドウに表示すべき.
    • touch
      タッチ・インタフェースを持つデバイスに適した形で表示すべき.
    • wap
      "feature phone"に適した形で表示すべき.
  • prompt (OPTIONAL)
    再認証/認可の同意を要求するかどうか指定するスペース区切りの ASCII 文字列のリスト
  • none
    再認証/認可の同意を要求(表示)してはならない.
  • login
    再認証の同意を要求(表示)すべき.
  • consent
    再認証/認可の同意を要求(表示)すべき.
  • select_account
    複数アカウント前提の際に、アカウント選択を促すべき.
  • hint
    基本、(素?)無視。
    • id_token_hint (OPTIONAL)
      prompt=noneの時に使う
    • login_hint (OPTIONAL)
      複数アカウント前提の際に、識別子のヒントとして利用する。
  • その他

レスポンス・パラメタの追加・変更

  • Token Endpoint
    • id_token
      response_typeで要求した場合に追加される。
    • token_type
      Bearer もしくは Client が Authorization Server と交渉した他の token_type の値と規定。

TLS要件

以下との通信は、TLS を用いなければならない (MUST).

  • Authorization Endpoint
  • Token Endpoint

その他の追加要件

  • Token Response に 以下の HTTP レスポンスヘッダーを指定(MUST).
    #Header NameHeader Value
    1Cache-Controlno-store
    21Pragmano-cache

Authorization Code Flow

概要

OAuth 2.0 からのステップ上の拡張部分は無い。

ただし、

ステップ

朱書きは、OAuth 2.0 からのステップ上の変更・拡張部分。

The Authorization Code Flow goes through the following steps.

  1. Client prepares an Authentication Request containing the desired request parameters.
  2. Client sends the request to the Authorization Server.
  3. Authorization Server Authenticates the End-User.
  4. Authorization Server obtains End-User Consent/Authorization.
  5. Authorization Server sends the End-User back to the Client with an Authorization Code.
  6. Client requests a response using the Authorization Code at the Token Endpoint.
  7. Client receives a response that contains an ID Token and Access Token in the response body.
  8. Client validates the ID token and retrieves the End-User's Subject Identifier.

Implicit Flow

  • scope="* openid *"

概要

ステップ

朱書きは、OAuth 2.0 からのステップ上の変更・拡張部分。

The Implicit Flow follows the following steps:

  1. Client prepares an Authentication Request containing the desired request parameters.
  2. Client sends the request to the Authorization Server.
  3. Authorization Server Authenticates the End-User.
  4. Authorization Server obtains End-User Consent/Authorization.
  5. Authorization Server sends the End-User back to the Client with an ID Token and, if requested, an Access Token.
  6. Client validates the ID token and retrieves the End-User's Subject Identifier.

ポイント

Hybrid Flow

  • response_type=
    • "code token"
    • "code id_token"
    • "code id_token token"

概要

IDトークンと同時に、アクセストークンや認可コードが一緒に発行される。

  • Hybrid な Flowであるため、
  • 前段・中段・後段
  • 中段:Implicit Flow
    認可エンドポイントからRedirectエンドポイントへ、
    Implicitなフラグメント部を使用したリダイレクトをするまで。
  • 後段:Hybrid Flow
    UserAgent?側でフラグメント部のcode, id_token, tokenを取得、
  • codeをClientで利用する。
    その後、UserAgent?がClientにcodeを送付し、
    Client側でcodeを使用してアクセストークン・リクエストを行う。

ステップ

朱書きは、Authorization Code Flowとの差異。

The Hybrid Flow follows the following steps:

  1. Client prepares an Authentication Request containing the desired request parameters.
  2. Client sends the request to the Authorization Server.
  3. Authorization Server Authenticates the End-User.
  4. Authorization Server obtains End-User Consent/Authorization.
  5. Authorization Server sends the End-User back to the Client with an Authorization Code and,
    depending on the Response Type, one or more additional parameters.
  6. Client requests a response using the Authorization Code at the Token Endpoint.
  7. Client receives a response that contains an ID Token and Access Token in the response body.
  8. Client validates the ID Token and retrieves the End-User's Subject Identifier.

ポイント

  • codeをUserAgent?からClientに渡す方法
    定義されていないが、クライアント側・サーバ側の違いはあるが、
    双方ともClientなので、恐らく、POSTなどでcodeをUserAgent?からClientに渡せば良さそう。
  • codeとtokenのaccess_tokenの差異
    セキュリティ特性によって以下が異なって良いと定義されている。
    • scope
    • expires_in
  • Authorization Endpoint と Token Endpoint から返されるIDトークンのクレームについて以下が必要になる。
  • issクレームと subクレームは同一でなければならない (MUST).
  • 両方に同じ Authentication イベントに関する Claim を含めるべき(SHOULD).
  • End-User に関するクレームは、
    Authorization Endpoint ≦ Token Endpointから返すクレームとしてよい (MAY).
    ただし、クレームが両方に存在する場合, その値は同値であるべき (SHOULD).

主要な仕様

subクレームの種類

(Subject Identifier Types)

  • 「5.7. Claim Stability and Uniqueness」で言われているように、
    • 通常、subクレーム値は、iss内で一意
    • 故に、エンドユーザにとっては、iss+subで一意
  • 故に、「8. Subject Identifier Types」では、
    • pairwiseというオプションで、
    • Client毎にsubクレーム値を変えることにより、
    • Clientを跨った名寄せを困難にしてプライバシーを保護する。

種類

  • public
    全ての Client に対し同一の subクレーム値を提供する(既定値)
  • pairwise
    各々の Client に対し異なる subクレーム値を提供する。

サポート

pairwiseの値

pairwiseのsubクレーム値

  • 要件
    • subクレーム値が, OP(IdP/STS) 以外の Party にとって, 可逆であってはならない (MUST NOT).
    • 異なる Sector Identifier 値は, 異なる Subject Identifier 値にならなければならない (MUST).
    • 同じ入力に対して必ず同じsubクレーム値となる決定的アルゴリズムでなければならない (MUST).
  • 計算例
    • sub = SHA-256 ( sector_identifier || local_account_id || salt )
    • sub = AES-128 ( sector_identifier || local_account_id || salt )
    • GUID = ローカルアカウントID, Sector Identifier(変換テーブル)

IDトークン

暗号関連

ユーザー属性

ユーザー属性クレーム群

ユーザー情報エンドポイント

追加の仕様

追加された仕様についてまとめる。

追加の応答タイプ (response_type)

追加の応答モード (response_mode)

オプションの仕様

認証コンテキスト クラス

Requestオブジェクト

クライアント認証

Self-Issued OP

CIBA Flow

その他

Offline Access

offline_access scopeにより、

  • Clientは、Resource Ownerの代わりに、長期間にわたってリソースにアクセスできる。
  • このため、このパラメタは、Refresh Tokenの発行に関係する。

Session Management

  • Draft: OpenID Connect Session Management 1.0 - draft 28
    http://openid.net/specs/openid-connect-session-1_0.html
    • エンドユーザのログインステータスを監視する方法を定義
    • IdP/STS(OP)上でユーザーがログアウトしたときにClient(RP)側から検知する方法など、セッション管理の方法
    • Client(RP)が、IdP/STS(OP)からログアウトしたエンドユーザを検知してClientからもログアウトできるようにする。

ログイン開始エンドポイント

アプリXのログイン・フローが、サード・パーティーの
Client(RP)やIdP/STS(OP)によって開始される仕組み。

  • 要するに、サード・パーティーのClient(RP)やIdP/STS(OP)から、
    • リダイレクト(とは言え、GETとPOST要求を受入)で
    • Client(RP)のログイン開始エンドポイントに遷移し、
    • IdP/STS(OP)に認可リクエストを送信する。
    • IdP/STS(OP)で認証後、Client(RP)のRedirectエンドポイントに遷移し、
    • 更に、その後、指定されたランディング・ページに遷移する。
  • パラメタ
  • iss (REQUIRED)
    認可リクエストを送信するIdP/STS(OP)を示す
  • login_hint (OPTIONAL)
    認可リクエストにlogin_hintパラメタ値として含める.
  • target_link_uri (OPTIONAL)
    • Redirectエンドポイントから、指定されたランディング・ページに遷移。
    • オープンリダイレクターとして使用されることを防ぐためtarget_link_uri値を検証する (MUST).

考慮点

IdP/STS(OP)の実装

必須の実装

  • すべてのIdP/STS(OP)
  • 署名: RS256
  • 認可画面 管理機能を用いた事前の認可の同意など
    • display
    • prompt
  • Locales
    • ui_locales
    • claims_locales
  • 認可リクエスト・パラメタへ対応
    • max_age
    • acr_values
  • 以下のクレームの格納要求
    • auth_time
  • 動的なIdP/STS(OP)
  • Response Type
    • id_token
    • code (Self-Issued OP 以外)
    • id_token token (Self-Issued OP 以外)
  • UserInfo? Endpoint (Self-Issued OP 以外)
  • JWK 公開(jwks_uri、X.509 形式でも可)
  • Requestオブジェクトのrequest_uri

Client(RP)次第の実装

Discovery、Dynamic Client Registration

事前登録のない Client(RP) と IdP/STS(OP) 間の
予期しないやりとりをサポートすることを選択した場合に実装が必要。

セキュリティ

OAuth 2.0 Threat Model and Security Considerations

サーバ認証

ID Tokenの署名・暗号化で提供される。

トークン

  • トークン生成
    • JWT([[JWS])を使用する。
    • TLS を使用する。
  • アクセス許可の制限
    aud の scope に対して制限をかける。
  • 有効期限の制限
    code, access_token, refresh_token,
  • 置換攻撃の防止
    • iss(完全一致)
    • sub
    • aud
    • azp
    • at_hash
    • c_hash

暗号化

  • 各実装は TLS をサポート
  • 共通鍵暗号
    HS256などのMACを使用する場合、client_secret は最低でも32オクテットが必要
  • 暗号関連の様々な攻撃
    • タイミング・アタック
    • JWT
      • JWT の Security Considerations
      • JWT が参照する, 各脆弱性を防ぐための仕様群

Requestオブジェクト

リクエストの漏洩や改ざんの防止

  • 特に、max_age と acr_valuesなどの改ざん防止。
  • 特に、claims や acr_valuesなどの漏洩防止

参考

OpenID Foundation

OpenID ファウンデーション・ジャパン

Client Implementer's Guide

WebアプリケーションのClientに当該フローを実装する場合の実装ガイド。

Qiita

TakahikoKawasaki?

IdM実験室

WIF

WIF Extension for OAuthは古い?

OWIN

Microsoft.Owin.Security.OpenIdConnect?

  • IdM実験室: [AAD/ASP.NET]

ADFS

OpenID Connectのシーケンス

STEP 0 は事前準備なので、STEP 1 からが実際の認証・認可のシーケンス。

Webアプリ(Basic Client Profile)

  • 概要
    Basic Client Profile:OAuth 2.0 Authorization Code Grantを拡張
  • STEP 0 : 事前準備(IdP/STS(OP)にClient(RP)を登録)
    • IdP/STS(OP)にClient(RP)を登録し、下記を入手する。
      • アプリケーションID(client_id)
      • シークレット(client_secret)
  • STEP 1 : Authorization codeの取得
    • Client(RP)がIdP/STS(OP)からAuthorization codeを取得。
    • スターターのリクエストをIdP/STS(OP)に送信する。
      • 電文
        https://・・・IdP/STS(OP)のAuthorization code取得用のURL・・・?
            response_type=code+id_token
            &client_id={client_id}
            &redirect_uri=・・・Client(RP)のURL・・・
            &state=CSRF対策のランダム文字列
            &scope=openid+profile
            &nonce=リプレイアタック対策のランダム文字列
  • 上記のパラメタの説明
    #パラメタ必須説明
    1response_type「code」と「id_token」を指定
    2client_id事前に準備したclient_idの値を指定
    3redirect_uriアプリケーションID登録時のコールバックURLに入力したURLを指定
    4stateCSRF対策のランダム文字列を指定
    5scope・openid:ユーザー識別子を取得(必須)
    ・profile:姓名・生年・性別が取得
    ・email:メールアドレスと確認済みフラグを取得
    ・address:ユーザー登録住所情報が取得
    6nonceImplicit or Hybrid Flowでid_tokenを取得する際は必須リプレイアタック対策のランダム文字列を指定
    7displayユーザのUIを選択:
    ・page(PC用UI、デフォルト値)
    ・touch(スマートフォン用UI)
    ・wap(フィーチャーフォン用UI)
    ・inapp(ネイティブアプリ用UI)~
    8その他、IdP/STS(OP)独自パラメタ
  • 成功すると認証/認可の同意画面が表示される。
    一度同意すると、次回以降、認証/認可の同意画面は省略される。
  • 認証/認可の同意が完了する(もしくは事前に認証/認可の同意をしている)と、
    以下のようなURLで「・・・Client(RP)のURL・・・」にリダイレクトされる。
    • 電文
      http://・・・Client(RP)のURL・・・?code=xxxxxxxx&state=CSRF対策のランダム文字列
    • 上記のパラメタの説明
      #パラメタ説明
      1code”code=xxxxxxxx”を取得する。
      2state”state=CSRF対策のランダム文字列”が、一致していることを確認する。
  • STEP 2 : Access Token、ID Tokenの取得
    • Tokenを取得する際は、POSTでリクエストを送信する
      (HTTPリクエストのヘッダーやデータにTokenリクエストに必要な値を指定する必要がある)
      ため、CUIのcURLコマンドを使用して、Access Token、ID Tokenを取得する。
  • cURLコマンドなどでリクエストする。
    • 電文
      #部分説明
      1HeaderAuthorization: Basic {basicAuth}
      2URLhttps://・・・IdP/STS(OP)のAccess Token、ID Token取得用のURL・・・?grant_type=authorization_code&code=・・・&redirect_uri=・・・"
  • 上記のパラメタの説明
    #パラメタ必須説明
    1{basicAuth}基本認証を使用したクライアント認証のため、
    アプリケーションID(client_id)、シークレット(client_secret)を":"区切りで結合しBase64文字列化
    2grant_typeauthorization_code という固定文字列を指定
    3codeAuthorization codeを指定、リクエスト送信後は使用できなくなる。
    4redirect_uriSTEP 1 のredirect_uriで指定したURLを入力。
  • 以下の様なレスポンスが返る。
    • 電文
      {
          "access_token":"{ヘッダー部}.{ペイロード部}.{シグネチャー部}",
          "token_type":"bearer",
          "expires_in":"3600",
          "refresh_token":"・・・",
          "id_token":"・・・"
      }
  • STEP 3 : IDトークンの正当性の検証
    • "access_token"の{ヘッダー部}を取り出して、base64デコード。
      • {ヘッダー部}の電文
        {
            "typ":"JWT",
            "alg":"HS256"
        }
  • {ヘッダー部}のパラメタの説明
    #パラメタ説明
    1typtyp:JWT(JSON Web Token)
    2algalg:HMAC-SHA256(署名に使用したハッシュ)
  • {ペイロード部}を取り出して、base64デコード。
    • {ペイロード部}の電文
      {
          "iss":"https:\/\/・・・Access Tokenの発行元URL・・・",
          "user_id":"ユーザー識別子",
          "aud":"アプリケーションID(client_id)と一致する値",
          "iat":IDトークンの発行時刻,
          "exp":IDトークンの有効期限,
          "nonce":"STEP 1 のnonceと一致する値"
      }
  • 署名の検証
    • "{ヘッダー部}.{ペイロード部}"を使用して、
      {ヘッダー部}のalg:HMAC-SHA256でバイナリ形式でハッシュ化。
    • それをBase64文字列化した文字列が"{シグネチャー部}"と一致していることを確認する。
  • STEP 4 : 属性情報の取得
    Client(RP)がIdP/STS(OP)で認証したユーザ属性情報を取得する。
  • ユーザー情報エンドポイントに、以下の形式でAccess Tokenを渡す。
    • 電文
      #部分説明
      1Header'Authorization: Bearer {access_token}'
      2URLURL:https://・・・ユーザ属性情報の発行元URL・・・?schema=openid
  • 上記のパラメタの説明
    {access_token}に、準備、STEP 0-3 で取得したAccess Tokenを使う。
  • 以下のユーザ属性情報を含んだクレームが取得できる。
    • 電文
      {
          "user_id":"・・・",
          "name":"・・・",
          "given_name":"・・・",
          "given_name#ja-Kana-JP":"・・・",
          "given_name#ja-Hani-JP":"・・・",
          "family_name":"・・・",
          "family_name#ja-Kana-JP":"・・・",
          "family_name#ja-Hani-JP":"・・・",
          "gender":"male or female",
          "birthday":"YYYY",
          "locale":"ja-JP,etc."
      }

モバイルアプリ(Implicit Client Profile)

  • 概要
    • Implicit Client Profile:OAuth 2.0 Implicit Grantを拡張
    • Webアプリ(Basic Client Profile)との違い
      • STEP 0は、前提の違いによる差異。
      • STEP 1以降は、Implicit Flowがベースとなっている。
  • STEP 0 : Discovery & Dynamic Client Registration
    IdP/STS(OP)探索と動的なClient(RP)登録
  • IdP/STS(OP)探索
    「○○のIDでログイン」というリンクを選択する替わりに、
    次の2種類の値をIdP/STS(OP)特定(Discovery)のためのヒントとして利用できる。
  • 動的なClient(RP)登録
    Client(RP)登録用エンドポイントにPOSTリクエストを送ることで、
    動的なClient(RP)登録(Dynamic Client Registration)もできる。

結果的に、IdP/STS(OP)からClient(RP)識別のための“cient_id”がレスポンスされる。

  • STEP 1 : Authorization Request
    認可リクエスト
  • STEP 2 : Authorization Response
    認可応答

OpenId? Connectのサンプル

Microsoft.Owin.Security.OpenIdConnect?

AzureADに対して、OpenId? Connectを使用して認証する。

https://github.com/OpenTouryoProject/SampleProgram/tree/master/ASPNET/AuthN_AuthZ/OpenID_Connect/

  • サンプル・アプリケーションをAzure Active Directoryに登録
    1. Azureの管理ポータルにサインイン。
    2. Azure Active Directoryのタブを開く。
    3. サンプル・アプリケーションを登録するテナント(ドメイン)を開く。
    4. [Applications]タブに移動し、ページの下部の[Add]アイコンををクリック。
    5. [What do you want to do?]画面で[Add an application my organization is developing]を選択。
    6. [Tell us about your application]画面が表示される。
      1. アプリケーションの名前を入力(例:OpenIDConnect_sample)。
      2. [Web Application and / or Web API]を選択する。
      3. [Next]をクリックする。
    7. [App properties]画面が表示される。
      1. サンプルのサインオンURLを入力(例:https://localhost:xxxxxx/
        サンプル・プロジェクトのプロパティにある開発サーバのSSL URLプロパティを指定
        http://www.codeproject.com/Tips/766918/Visual-Studio-Use-HTTPS-SSL-On-Web-Application-Pro
      2. アプリのID URIを入力(例:https://<your_tenant_name>/OpenIDConnect_sample)
        '<your_tenant_name>はAzure ADのテナント(ドメイン)名。
      3. [Complete]をクリック。
  • サンプル・アプリケーションの構成
    1. web.configファイルを開く。
    2. FxTenant?にAzure ADのテナント(ドメイン)名を指定(例:xxxxx.onmicrosoft.com)
    3. FxClientId? にAzureのポータルから入手することができるClient IDを指定
      1. クライアントIDを取得するには、
      2. Azureの管理ポータルにサインイン。
      3. Azure Active Directoryのタブを開く。
      4. サンプル・アプリケーションを登録したテナント(ドメイン)を開く。
      5. [Applications]タブに移動しサンプル・アプリケーションを選択。
      6. アプリケーション画面で[ACCESS WEB APIS IN OTHER APPLICATIONS]を選択。
      7. Client IDをコピー。
    4. FxPostLogoutRedirectUri?にサンプルのサインオンURLを入力(例:https://localhost:xxxxxx/
  • サンプル・アプリケーションの実行

    F5実行でリダイレクトされた先のAzure AD(IdP/STS(OP))で認証できることを確認する。

Microsoft Azure Active Directory

Azure Active Directory B2C

子ページ

IDトークン

ユーザー属性クレーム関連

暗号関連

Discovery

Dynamic Client Registration

クライアント認証

認証コンテキスト クラス

Requestオブジェクト

Self-Issued OP

CIBA Flow


Tags: :IT国際標準, :認証基盤, :クレームベース認証, :OAuth


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-12-18 (火) 11:22:01 (23h)