Upgrade to Pro — share decks privately, control downloads, hide ads and more …

わかった気になる!OpenID Connect

patorash
February 29, 2020

わかった気になる!OpenID Connect

OAuth2.0の挙動がどうなっているのかを掘り下げ、OpenID ConnectとOAuth2.0の仕様と挙動を比較しながら、OpenID Connectのことをざっくりとわかってもらうことをゴールとしています。
また、RailsでOAuth2.0を使う方法やOpenID Connectを使うための方法のヒントを書いています。デモでコードは見せましたが、資料にはコードは載せていません。

2020-03-03: 間違いの指摘を受けたので、内容を修正しました。
2020-03-04: UserInfoエンドポイントに関する箇所を修正しました。

patorash

February 29, 2020
Tweet

More Decks by patorash

Other Decks in Technology

Transcript

  1. わかった 気になる ! OpenID Connect 2020-02-29 第22回 岡山Ruby, Ruby on

    Rails勉強会 株式会社リゾーム 尾古 豊明
  2. 修正履歴 • 2020-03-03: ◦ OAuth認証の正体の箇所を、プロフィール APIから取得したユーザ識別子を認証機能として使った もの、に変更 ◦ IDトークンから安全にユーザ識別子が取得できた時点で認証完了と変更 以前はUserInfoエンドポイントとIDトークンのペイロードの内容を比較して認証完了としていたが、

    勘違いしていた ◦ UserInfoエンドポイントを必須のフローではなく、必須の APIに変更 リライング・パーティでプロフィールを使うときに利用するものだった。 以前は認証するために必要なフローの一部だと勘違いしていた。 ◦ OAuth2.0の流れから要点を押さえる、の箇所で twitterを題材にしていたが、 twitterはOAuth1.0とい う指摘を頂いたので GitHubに変更 • 2020-03-04 ◦ UserInfoエンドポイントのsubとIDトークンのsubを比較するすることでアクセス・トークンのすり替え に気付ける、という記述を削除。 OIDCだと別の確認手段があるため。 ◦ UserInfoエンドポイントの説明に、フォーマットが標準化されていることがメリットであることを記述し た。
  3. 目次 1. 自己紹介 2. この発表のゴールについて 3. シングルサインオン 4. OAuthは認証なのか?OAuth2.0の流れから要点を押さえる 5.

    OAuth2.0とOpenID Connectの関係 6. OpenID Connectをわかった気になる 7. OAuth2.0とOpenID Connectの付与方式 8. Implict Grantの危険性について 9. RailsでOAuthするには? 10. RailsでOpenID Connectするには? 11. まとめ
  4. 自己紹介 名前:尾古 豊明(おこ とよあき) twitter: @patorash 所属:株式会社リゾーム システム開発部 役職:専門職 仕事内容:

    ショッピングセンターに関連するサービス開発 Ruby on Railsで自社サービスの開発・運用(7年目) ここ最近はMacのRubyがセグメンテーション違反を吐き始め、 開発に支障が出まくっているので開発環境のAll Docker化に取り組んでいる 4
  5. この発表のゴールについて • この発表のゴール ◦ OAuth2.0がどういうものかをわかってもらう ◦ OpenID Connectがどういうものかをわかってもらう ◦ RailsでOpenID

    Connectする方法をざっくりわかってもらう • この発表でしないこと ◦ OAuth2.0やOpenID Connectの細かいところは説明しない ◦ OAuth2.0の危険なところ等についても(詳しくは)説明しない
  6. シングルサインオン(SSO)とは? 1つのIDとパスワードを入力して、複数のWebサービスやアプリケーションにログインする仕組み。
 入力や管理の手間を省き、セキュリティを強化することができる。
 例えば、メール、SNS、Google、Amazon、グループウェアなどのサービスごとに別々のIDとパスワードを設定すると、アクセスするた びにパスワードを入力する労力がかかる上、パスワードを忘れると再設定する手間もかかる。また、簡単なパスワードを設定して使 い回したり、メモなどで残したりすると、流出や漏えいのリスクが高くなる。
 シングルサインオンは1つのIDとパスワードでサービスが利用できるので、パスワードを管理する負担から解放され、利便性が向上 し、セキュリティリスクが減る。また、企業のシステム管理者の労力も省かれ、生産性が向上する。
 シングルサインオンを実現する認証方式は、大きく分けて4つある。Windows Server

    Active Directoryの認証に使われる「ケルベロス 認証方式」、WebブラウザーやWebアプリケーションのサーバーの間にリバースプロキシサーバーを設置する「リバースプロキシ方 式」、Webアプリケーションのサーバーにエージェントソフトを組み込む「エージェント方式」、パスワードの代わりに「チケット」と呼ばれ る情報を受け渡しする「フェデレーション方式」がある。
 
 シングルサインオン( SSO) | IT用語辞典 より https://www.otsuka-shokai.co.jp/words/single-sign-on.html
  7. OAuth2.0とOpenID Connectの違い OAuth2.0 OpenID Connect やること 認可(委譲) 発行するもの プロフィール参照API スコープ

    アプリケーション毎に任意 ※認可(委譲)する対象はスコープに提示されている権限
  8. OAuth2.0とOpenID Connectの違い OAuth2.0 OpenID Connect やること 認可 発行するもの アクセス・トークン プロフィール参照API

    アプリケーション毎に任意 (GitHubでは存在する) スコープ アプリケーション毎に任意
  9. OAuth2.0とOpenID Connectの違い OAuth2.0 OpenID Connect やること 認可 発行するもの アクセス・トークン プロフィール参照API

    アプリケーション毎に任意 (GitHubでは存在する) スコープ アプリケーション毎に任意
  10. OAuth2.0とOpenID Connectの違い OAuth2.0 OpenID Connect やること 認可 認可+認証 発行するもの アクセス・トークン

    アクセス・トークン+IDトークン プロフィール参照API アプリケーション毎に任意 (GitHubでは存在する) UserInfoエンドポイントが必須 スコープ アプリケーション毎に任意 プロフィール系のスコープ定義が 必須。リソースはアプリケーション毎に 任意。 認証を目的としたIDトークンにユーザ識別子(ユーザ ID等)を設定する。 安全にユーザ識別子を取得できた時点で認証と言える。 (「安全に」については後述)
  11. OAuth2.0との違いはIDトークンの有無 • フォーマットは署名付きJWT • JWT(JSON Web Token)とは? ◦ 読み方は「ジョット」らしい ◦

    ヘッダー、ペイロード、署名の 3つのJSON文字列をBASE64URLエンコードして ピリオドで連結したもの(ヘッダー .ペイロード.署名)
  12. IDトークン(ペイロード) • iss...Issuer(イシュアー)。IDトークン発行者 • aud...Audience(オーディエンス)。リライング・パーティのID • sub...Subject(サブジェクト)。エンドユーザーの識別子(ユーザIDとか) • iat...Issued At。JWTの発行時間。

    • exp...Expiration time。IDトークンの有効期限 • nonce...リプレイアタック防止用の文字列 これらは一部であり、その他のプロフィール等、色々と含ませることが可能 Authorization Code Flowの場合、 署名の検証なしでsub(ユーザ識別子)を取得できた時点で認証完了。 リライング・パーティとIDプロバイダ間で直接通信をしているため、 安全と言える。 Implicit Flowの場合、 署名を検証後にsub(ユーザ識別子)を取得できた時点で認証完了。 署名を検証することで改ざんはなかったと保証できるので安全と言える。
  13. IDトークン(署名) • ヘッダー+’.’+ペイロードを秘密鍵で署名したものを BASE64URLエンコーディングした文字列 • 共通鍵方式と公開鍵方式があるが、公開鍵方式が一般的 • IDプロバイダは、秘密鍵で署名する • リライング・パーティはIDプロバイダから公開鍵を取得して、

    署名を検証する • 署名の方式は、ヘッダーのalgに定義されている • 公開鍵はJWK(JSON Web Key)形式で配布される • Authorization Code Flowの場合は署名の検証が必須ではない ◦ 署名の検証をしなくても、認可コードのやり取りでリライング・パーティーと IDプロバイダ間で通信していることが明白なため、らしい • Implicit Flowの場合は署名の検証が必須 • ヘッダー+ペイロード == 復号化した署名 ◦ 一致しなければ、改ざんされている
  14. 最後にUserInfoエンドポイントにアクセス • UserInfoエンドポイントにはアクセス・トークンを使う • OpenID Connectは個人情報取得のためのAPIの実装が必須 • 認証以外の目的でユーザ情報を利用する場合に利用 • レスポンスにはsubクレーム(ユーザ識別子)が必ず含まれる

    ◦ IDトークンで取得済みのユーザ識別子と UserInfoエンドポイントで取得した ユーザ識別子が一致することを必ず確認しなければならない。 • フォーマットが標準化されているため、パースしやすい。 (OAuth2.0の場合はフォーマットが定義されていないため、  認可サーバ毎に独自のフォーマットを採用)
  15. OAuth2.0とOpenID Connectの付与方式 OAuth2.0 OpenID Connect(OIDC) 説明 Authorization Code Grant Authorization

    Code Flow クライアントがネット上に存在 最も推奨されている手法 Implicit Grant Implicit Flow クライアントがブラウザアプリ orスマ ホアプリなど 非推奨となっている(OAuthでは) Client Credentials Grant - リソースが個人に紐づいていない ケース マスターデータ配布等 Resource Owner Password Credentials Grant - IDとパスワードをクライアントに渡 す方式。普通は使わない。 ハイブリッドフロー ハイブリッドフロー Authorization Code FlowとImplicit Flowのハイブリッド • OAuthはGrant • OIDCはFlow セキュリティ的に最も優れているので オススメ。 クライアントがWebアプリなら、 普通はこれになる。
  16. gem doorkeeper-openid_connect • doorkeeperでOAuthの認可サーバが構築できていることが前提 ◦ OpenID ConnectはOAuth2.0の拡張だから • OpenID Connectの機能を追加する

    • OpenID Connectの知識がないと設定ファイルの意味が全くわからない • 日本語どころか、英語でも情報が少ない
  17. IDプロバイダ(認可サーバ)側 • gem ◦ devise ◦ doorkeeper ◦ doorkeeper-openid_connect •

    config/initializers/doorkeeper_openid_connect.rbで設定 ◦ issuerの設定 ◦ 秘密鍵の指定 ◦ 秘密鍵のアルゴリズムの指定 ◦ ユーザをアクセス・トークンで取得する方法の定義 ◦ subject(ユーザを一意に判定する値)の定義 ◦ claims(クレーム。要求のこと)の定義 ▪ IDトークンのペイロードと UserInfoエンドポイントに含まれる情報の定義 • doorkeeperにリライング・パーティの情報を登録 ◦ client_idとclient_secretの発行 ◦ callback urlの登録 ◦ スコープの登録(openidは必須)
  18. リライング・パーティ(クライアント)側 • gem ◦ devise ◦ omniauth-openid_connect • config/initializers/devise.rb ◦

    omniauthで認証するストラテジーの情報の定義 ▪ IDプロバイダに発行してもらった client_id, client_secretを設定 ▪ issuerの情報を登録 ▪ discovery: trueだと、公開鍵を探してくれる • /.well-known/openid-configuration • app/controllers/users/omniauth_callbacks_controller.rb ◦ リダイレクトしてきたときの処理を追加する • app/models/user.rb ◦ 認証情報からユーザを取得する処理を追加する
  19. まとめ • OAuth2.0は、認可のプロトコル • OpenID Connectは、OAuth2.0を拡張した認証のプロトコル • 付与方式は、Authorization Code Grant(Flow)を使おう

    ◦ Implicit Grantはダメ、絶対(OAuthの場合) ◦ OpenID ConnectならImplicit Flowを使うのは有り(署名があるから) • アクセス・トークンは切符と同じ • OAuth2.0は仕様を満たしているからといって安全とは言えない場合がある • RailsでOAuth2.0のプロバイダを実装するならgem doorkeeperが楽 • RailsでOpenID Connectのプロバイダを実装するなら gem doorkeeper-openid_connectが楽 ◦ ただし、OpenID Connectの理解は必要