2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

OpenID Connect 入門: 土岐 孝平 (著) のまとめ

Last updated at Posted at 2021-10-11

OIDCについて勉強する必要がでたので、OpenID Connect入門: 概念からセキュリティまで体系的に押さえる Kindle版, 土岐 孝平 (著)を読んでまとめてみました。

まだ勉強したてのため、理解が間違っているかもしれませんので、参考程度に。
詳細は上記書籍を見るようにしてください。薄い本ですのですぐ読めます。オススメです。

OAuth2.0

OAuth2.0とは

  • OAuth2.0は、2012年に公開された認可のためのHTTPベースのプロトコル
  • RFC6749で仕様が示されています。
  • アプリケーションに対してユーザが認可する
    • 例えば、名刺管理アプリがFacebookにアクセスし、友達のデータにアクセスしたい場合、ユーザが名刺管理アプリに対して、「Facebookの友達データにアクセスしてOK」と認可する

OAuth2.0の仕組み, アクセストークン

上記の例でいうと

  • ユーザはFacebookに対して、名刺管理アプリからの友達データへのアクセスを許可するよーと伝える
  • Facebookは、名刺管理アプリに対してアクセストークンを発行する
  • 名刺管理アプリはアクセストークンを使って、友達データにアクセスさせる

OAuth2Overview

OAuth2.0の問題点

  • 認可だけでなく、認証もさせちゃうと便利だよね。上記だとFacebook
  • でもOAuthは、"認証時の情報", "ユーザの情報" を取得するための仕様が定められていないよね!
    • 認証時の情報: 認証の日時, 手段
    • ユーザの情報: ユーザのID, 名前, メールアドレス
  • こまでは上記情報を、各自独自実装して提供していたので面倒だよね〜

OIDC (OpenID Connect)

OIDCとは

OIDCとは OAuth2.0をユーザ認証としても活用するために拡張したもの

  • 2014年、OpenID Foundation が仕様 OpenID Connect Core 1.0 incorporating errata set 1 を公開
  • 主な拡張としては以下を定めた
    • 認証時の情報とユーザ情報を記載したIDトークン
    • ユーザ情報を取得するためのエンドポイント (IDトークンにある程度ユーザ情報が含まれるので不要なときもある)

IDトークンのデータ形式については、以下で詳細に説明しています。

OIDCの登場人物

役割 OAuth2.0の呼び方 OIDCの呼び方 本書の呼び方
アプリケーションを使うユーザ Resource Owner End User ユーザ
ユーザが操作する端末 User Agent 定義なし ユーザ端末
アクセストークンを発行するサーバ Authorization Server OpenID Provider Authorization Server
アクセストークンを発行してもらうアプリケーション Client Relying Party Client
アクセストークンを使ってアクセスされるサーバ Resource Server 定義なし Resource Server

OIDCの搭乗人物

エンドポイント

3つのエンドポイントを覚えましょう。

  • 認可エンドポイント
    • エンドポイントの場所: Authorization Server
    • 意味: ユーザの認証,認可を提供するエンドポイント
  • トークンエンドポイント
    • エンドポイントの場所: Authorization Server
    • 意味: トークンを取得するためのエンドポイント。ClientがトークンリクエストをするためのURL
  • リダイレクションエンドポイント
    • エンドポイントの場所: リソースサーバ (提供者はClientであり例えばブラウザ上のJavacsriptである)
    • 認証認可後、リダイレクトされClientが受け取るためのエンドポイント

フローの種類

OICDのフローの種類を以下に紹介します。まずはSPA認可コードフローを勉強すればよさそうなため、簡単な紹介に留めます。
各種シーケンス図はこちらを参照してください。

  • SPA認可コードフロー
    • OIDCの認可フローとしてもっとも一般的。まずはこれを深く勉強しよう。
    • Clientの種類: ブラウザ上のJavaScript, Web ServerはJSをダウンロードするだけのサーバ
  • MPA認可コードフロー
    • Multi Page Applicationは、リクエスト毎にサーバ側でHTMLを生成する昔ながらのWebアプリケーション。必要に応じて習得すればよい
    • Clientの種類: Web Server上のアプリケーション
  • ネイティブアプリの認可コードフロー
    • iPhoneアプリやAndroidアプリなどのネイティブアプリ
    • Clientの種類: ネイティブアプリ
  • インプリシットフロー
    • 認可レスポンスのリダイレクションエンドポイントのURLに直接トークンの値を含める
    • CORS(CrossOriginResourceSharing)が整備された後、OAuth2.0のドラフト「OAuth2.0securityBestCurrentPractice」では非推奨
    • Clientの種類: ブラウザ上のJavaScript
  • ハイブリッドフロー
    • 認可コードフローと同じ。認可レスポンスの中に、IDトークンやアクセストークンを含めることができる。
  • クライアントクレデンシャルフロー:
    • ユーザが関わらない、システムどうしのやりとりなどで使用
    • ClientIDとClientSecretを使って、AuthorizationServerからアクセストークンを取得
    • 利用シーンとしては、バッチ処理でユーザが管轄しないコンテンツ(例えば、商品データ・注文データ)
    • Clientの種類: ユーザが直接関わらないバックエンドのシステム
  • リソースオーナーパスワードクレデンシャルフロー:
    • 認証情報を一度Clientに渡す必要がありノンセキュア。OAuth2.0の仕様書に今後使うなという記載がある。一旦無視して良い。
    • Client: SNSサイトの公式のネイティブアプリなど。信頼性の高いサービス

SPA認可コードフローの詳細

OIDCの認可フローとしてもっとも一般的なSPA認可コードフローを詳細に見てみます。

  • 青色で示したフローと赤色で示したエンドポイントに注目しながら見てください
  • またこのシーケンス図はClientとAuthorization Serverの関係が詳しく書かれており、Resource Serverは示されていないことに注意してください(Web ServerはResource Serverでない)

SPA認可コードフロ-

Authorization Request

認可リクエストは、Authorization Serverに対して、フローを開始するための情報を指定します。具体的には、フローの種類や、Clientが許可してほしいアクセスの内容 Scope などです。情報はリクエストパラメータ(URLの後ろに?や&がつくやつ)で送信します。サンプルを以下に示します

Sample
https://server.example.com/authorize?
response_type=code
&response_mode=fragment
&scope=openid profile email
&client_id=myapp
&redirect_uri=https://client.example.org/app.html
&state=af0ifjsldkj
&nonce=n0S6_WzA2Mj
  • scope: scopeの名前を","区切りでつないだもの。"openid"は必須
    • Clientが許可してほしいアクセスの内容であり、仕様で示されている主なスコープは以下とおり。
      • openid: openidのリクエストを示す。必須
      • profile: ユーザのプロフィールのClaimを取得
        • Claimとは、認証時の情報やユーザの情報を、キーと値で表現したデータのこと
        • ClaimはIDトークンの中に含められたり、ユーザ情報エンドポイント(別の章で説明)のレスポンスに含められたりする。
      • email : ユーザのemailのClaimを取得
      • address : ユーザの住所のClaimを取得
      • phone : ユーザの電話番号のClaimを取得
  • response_type: 認可コードフローの場合は code を指定
    • 認可レスポンスで受け取るデータ。この指定によってフローが変わる。response_typeの値の種類と、使用されるフローの対応を以下の通り
      • 認可コードフローで使用される
        • code: Authorization Code
      • インプリシットコードフローで使用される
        • id_token: IDトークン
        • id_token token: IDトークン, アクセストークン
      • ハイブリッドフローで使用される
        • code id_token: 認可コード, IDトークン
        • code token: 認可コード, IDトークン
  • response_mode : query もしくは fragment を指定
    • 認可レスポンスでのデータの受け取り方を表す。
    • ?で渡すのがqueryで#で渡すのがfragment
      • https://sample.com/app.html?code=(省略)&state=(省略)
      • https://sample.com/app.html#code=(省略)&state=(省略)
    • SPAの場合はfragmentがベター
  • client_id: Authorization Serverが管理する Client ID
    • Authorization ServerがClientを登録するときに割り当てられる。
    • Client側はこのIDをAuthorization Request のときに付与できるように開発する必要がある。
  • redirect_uri: リダイレクションエンドポイントのURL
    • 認証、認可後のリダイレクトURL
    • 事前にAuthorization Serverへの登録も必要。
    • もしredirect_uriで指定されたURLと事前に登録されたURLが不一致の場合はエラーになる。
  • state : ランダムな任意の値
    • 認証・認可後のリダイレクト先のURLに含めてもらうランダムな値。
    • Client側で生成
    • リダイレクションエンドポイントへのCSRF(Cross Site Request Forgery)を防ぐ用途で使用
  • nonce : ランダムな任意の値
    • Client側で生成するランダムな値
    • Authorization ServerがIDトークンを発行するとき、この値も含めてくれる。これによりClientがIDトークンの正当性を確認できる。

Authorization Response

sample
HTTP/1.1 302 Found 
Location:https://client.example.org/app.html#
   code=SplxlOBeZQQYbYS6WxSbIA
   &state=af0ifjsldkj
  • Locationで Redirection Endpoint を指定します。
  • Authorization Request時、fragmentを指定している想定のため#でパラメターが渡されています。

各種パラメータの説明をします。

  • code: Authorization Serverが発行したAuthorization Code
  • state: Authorization Request時に付与したstateの値

Request to Redirection Endpoint

sample
GET /app.html
HOST:client.example.org

このケースではブラウザはfragmentの値が取り除き、Redirection Endpointである Web Server へアクセスします。

Token Request

sample
POST /token HTTP/1.1
Host:server.example.com
ContentType:application/xwwwformurlencoded

grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&client_id=myapp
&redirect_uri=https://client.example.org/app.html
  • grant_type: トークンを取得する手段
  • code: Authorization Serverが発行したAuthorization Code
  • client_id: Authorization Serverに事前に登録済みのclient_id
  • redeirect_uri: ClientのRedirection Endpoint

トークンレスポンス

sample
HTTP/1.1 200 OK
ContentType: application/json
CacheControl: nostore
Pragma: no-cache

{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"refresh_token": "8xLOxBtZp8",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI.....(省略)"
}
  • access_token : アクセストークン
  • id_token : IDトークン
  • refresh_token : リフレッシュトークン
  • token_type : Resource Severにトークンを送信する手段。通常はBearer を指定
  • expires_in : 有効期限[秒数]

IDトークンのデータ形式

JWTデータ形式

IDトークンは認証時の情報とユーザ情報がJWTのデータ形式で記述されています。このJWT形式には以下の2つがあります。基本的にはOIDCにおいてJWS形式が使われます

  • JWS(Json Web Signature) <= こちらが一般的
  • JWE(Json Web Encryption)

このJWSは以下の3つで構成され、これらを.でつなげたものが、IDトークンとなります。

  • ヘッダ
    • Base64URLで変換する
    • 電子署名した際のアルゴリズムが記載されている
  • ペイロード
    • Base64URLで変換する
    • Claim情報が記載
  • 電子署名
    • Base64URLで変換されたヘッダ+ペイロードのハッシュ値をAuthorization Serverの秘密鍵で暗号化

JWTFormat

Base64について補足しておきます。

  • Base64は、データを64種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にて日本語のように1バイト(255文字)に収まらないマルチバイト文字やバイナリデータを扱うためのエンコード方式です
  • Base64URL: URLアプリケーションのための変形Base64。Base64の+/をURLに混ぜると問題を引き起こすため、Base64URLでは、62番目の+-へ、63番目の/_に変更されている。その他パディングがなかったりする。詳細は上記Base64のリンクを参照

ペイロードに記載されるClaimの種類

標準的なClaimはRFC7519やOIDCの仕様で記載されている。主なClaimを以下に示します。

  • iss: Issuerの略。トークンの発行元
  • sub: Subjectの略。認証された主体。通常はユーザを表す
  • azp: AuthorizedPartyの略。ClientIDが設定される
  • aud: Audienceの略。トークンの読者を表す。基本的に、IDトークンの場合はClient ID、アクセストークンの場合はResource Serverの識別子が設定される
  • exp: ExpirationTimeの略。有効日時がUnix時間で表記される
  • iat: IssuedAtの略。発行日時がUnix時間で表記される
  • jti: JWTIDの略。トークンを一意に特定するためのID
  • acr: Authentication Context Class Referenceの略。認証の手段を表す値
  • nonce: 認可リクエストでClientが指定したnonceの値
  • name: ユーザの名前
  • profile: ユーザのプロフィールページのURL
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?