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勉強会
    株式会社リゾーム 尾古 豊明

    View full-size slide

  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エンドポイントの説明に、フォーマットが標準化されていることがメリットであることを記述し
    た。

    View full-size slide

  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. まとめ

    View full-size slide

  4. 自己紹介
    名前:尾古 豊明(おこ とよあき)
    twitter: @patorash
    所属:株式会社リゾーム システム開発部
    役職:専門職
    仕事内容:
    ショッピングセンターに関連するサービス開発
    Ruby on Railsで自社サービスの開発・運用(7年目)
    ここ最近はMacのRubyがセグメンテーション違反を吐き始め、
    開発に支障が出まくっているので開発環境のAll Docker化に取り組んでいる
    4

    View full-size slide

  5. この発表のゴールについて
    ● この発表のゴール
    ○ OAuth2.0がどういうものかをわかってもらう
    ○ OpenID Connectがどういうものかをわかってもらう
    ○ RailsでOpenID Connectする方法をざっくりわかってもらう
    ● この発表でしないこと
    ○ OAuth2.0やOpenID Connectの細かいところは説明しない
    ○ OAuth2.0の危険なところ等についても(詳しくは)説明しない

    View full-size slide

  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

    View full-size slide

  7. シングルサインオンのイメージ



    GitHubにログインしていれば、様々なサービスを利用できる。
    メリットは、個々のサービス毎にID、パスワードを管理しなくてもよいこと。

    View full-size slide

  8. OAuthは認証なのか?
    OAuth2.0の流れから要点を押さえる
    (Authorization Code Grant)

    View full-size slide

  9. OAuth2.0とOpenID Connectの違い
    OAuth2.0 OpenID Connect
    やること
    発行するもの
    プロフィール参照API
    スコープ

    View full-size slide

  10. これが
    スコープ!

    View full-size slide

  11. OAuth2.0とOpenID Connectの違い
    OAuth2.0 OpenID Connect
    やること
    発行するもの
    プロフィール参照API
    スコープ アプリケーション毎に任意

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  14. 認証に成功

    View full-size slide

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

    View full-size slide

  16. 初回でプロフィール情
    報を取得
    クライアントで
    プロフィールAPIから
    識別子を取得し、
    認証に利用

    View full-size slide

  17. OAuth認証の正体
    ● OAuth2.0の認可プロセスでは、アクセストークンの取得までで、
    プロフィールなど一切取得していない。
    ● 認可後に、アクセストークンを使って、プロフィールAPIから取得した
    識別子(ユーザID等)を認証機能に使っているだけ!
    ● 認可サーバにもプロフィール用のAPIを作らなければならない
    という仕様はない
    ○ 認可サーバの実装次第
    ○ クライアントの実装次第

    View full-size slide

  18. シングルサインオンのイメージ
    GitHubにログインしていれば、様々なサービスを利用できる。
    メリットは、個々のサービス毎にID、パスワードを管理しなくてもよいこと。
    デメリットは、悪意あるクライアントに過剰な権限を認可すると危険なこと。

    View full-size slide

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

    View full-size slide

  20. OAuth2.0とOpenID Connectの関係

    View full-size slide

  21. OpenID Connectとは?
    ● OAuth2.0を拡張した認証プロトコル
    ● 認証+認可
    ● アクセストークンとは別に、認証用にIDトークンを発行する
    ● UserInfoエンドポイントを定義することが仕様に含まれる
    ● プロフィール系のスコープを定義することが仕様に含まれる

    View full-size slide

  22. OAuth2.0とOpenID Connectの違い
    OAuth2.0 OpenID Connect
    やること 認可 認可+認証
    発行するもの アクセス・トークン アクセス・トークン+IDトークン
    プロフィール参照API アプリケーション毎に任意
    (GitHubでは存在する)
    UserInfoエンドポイントが必須
    スコープ アプリケーション毎に任意 プロフィール系のスコープ定義が
    必須。リソースはアプリケーション毎に
    任意。
    認証を目的としたIDトークンにユーザ識別子(ユーザ ID等)を設定する。
    安全にユーザ識別子を取得できた時点で認証と言える。
    (「安全に」については後述)

    View full-size slide

  23. ここ以外、OAuth2.0と
    ほぼ同じ!!
    仕様上、必須のAPI

    View full-size slide

  24. OpenID Connectをわかった気になる

    View full-size slide

  25. OAuth2.0との違いはIDトークンの有無
    ● フォーマットは署名付きJWT
    ● JWT(JSON Web Token)とは?
    ○ 読み方は「ジョット」らしい
    ○ ヘッダー、ペイロード、署名の 3つのJSON文字列をBASE64URLエンコードして
    ピリオドで連結したもの(ヘッダー .ペイロード.署名)

    View full-size slide

  26. IDトークン(ヘッダー)
    ● typ...JWT
    ● alg...RS256など、署名アルゴリズムを指定
    ● kid...公開鍵のID

    View full-size slide

  27. 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(ユーザ識別子)を取得できた時点で認証完了。
    署名を検証することで改ざんはなかったと保証できるので安全と言える。

    View full-size slide

  28. IDトークン(署名)
    ● ヘッダー+’.’+ペイロードを秘密鍵で署名したものを
    BASE64URLエンコーディングした文字列
    ● 共通鍵方式と公開鍵方式があるが、公開鍵方式が一般的
    ● IDプロバイダは、秘密鍵で署名する
    ● リライング・パーティはIDプロバイダから公開鍵を取得して、
    署名を検証する
    ● 署名の方式は、ヘッダーのalgに定義されている
    ● 公開鍵はJWK(JSON Web Key)形式で配布される
    ● Authorization Code Flowの場合は署名の検証が必須ではない
    ○ 署名の検証をしなくても、認可コードのやり取りでリライング・パーティーと
    IDプロバイダ間で通信していることが明白なため、らしい
    ● Implicit Flowの場合は署名の検証が必須
    ● ヘッダー+ペイロード == 復号化した署名
    ○ 一致しなければ、改ざんされている

    View full-size slide

  29. 最後にUserInfoエンドポイントにアクセス
    ● UserInfoエンドポイントにはアクセス・トークンを使う
    ● OpenID Connectは個人情報取得のためのAPIの実装が必須
    ● 認証以外の目的でユーザ情報を利用する場合に利用
    ● レスポンスにはsubクレーム(ユーザ識別子)が必ず含まれる
    ○ IDトークンで取得済みのユーザ識別子と UserInfoエンドポイントで取得した
    ユーザ識別子が一致することを必ず確認しなければならない。
    ● フォーマットが標準化されているため、パースしやすい。
    (OAuth2.0の場合はフォーマットが定義されていないため、
     認可サーバ毎に独自のフォーマットを採用)

    View full-size slide

  30. ここ以外、OAuth2.0と
    ほぼ同じ!!
    この時点で認証完了!
    仕様上、必須のAPI
    IDトークンのユーザ識別
    子とUserInfo
    レスポンスの識別子の比
    較でアクセス・トークンの
    すり替えに気付くことが
    できる

    View full-size slide

  31. おわかりいただけただろうか?

    View full-size slide

  32. 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アプリなら、
    普通はこれになる。

    View full-size slide

  33. Implicit Grantが危険という話
    ● クライアントがブラウザアプリorスマホアプリであるということ
    ● リバースエンジニアリングに弱い
    ○ DevToolsやデバッガ経由でアクセス・トークンが盗まれる危険性
    DevToolsでレスポンスボディを
    見たら、アクセス・トークンが
    丸見えじゃん。
    このアクセス・トークンを
    俺が作った悪意あるアプリで
    使っちゃうぞ~!!

    View full-size slide

  34. アクセス・トークンが盗まれたときの危険性
    ● アクセス・トークンは認可のためにある(認証ではない)
    ● アクセス・トークンを利用して依頼した処理は、
    認可サーバでは、「あなたが本当に依頼したかどうか」は、判別できない
    ○ アクセス・トークンが漏洩して、大量の DMを送られたとする。
    それはあなたが依頼したことですか?違いますね?
    ● アクセス・トークンは切符と同じ
    ○ 電車に乗るための認可の証
    ○ 電車に乗るのが誰なのかは、切符に紐づいていない
    ○ あなたの切符を使って第三者が電車に乗るということ

    View full-size slide

  35. 仕様を満たしている≠安全

    View full-size slide

  36. RailsでOAuthするには?

    View full-size slide

  37. gem doorkeeperを使え!

    View full-size slide

  38. gem doorkeeper
    ● RailsアプリケーションにOAuth2.0の認可サーバ機能を付けるためのgem
    ● チュートリアル通りにやれば、ほぼほぼハマることはない
    ● インターネットに沢山情報がある。日本語の記事も豊富

    View full-size slide

  39. RailsでOpenID Connectするには?

    View full-size slide

  40. gem
    doorkeeper-openid_connect
    を使え!

    View full-size slide

  41. gem doorkeeper-openid_connect
    ● doorkeeperでOAuthの認可サーバが構築できていることが前提
    ○ OpenID ConnectはOAuth2.0の拡張だから
    ● OpenID Connectの機能を追加する
    ● OpenID Connectの知識がないと設定ファイルの意味が全くわからない
    ● 日本語どころか、英語でも情報が少ない

    View full-size slide

  42. 時間があって、コードが動けばデモ

    View full-size slide

  43. 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は必須)

    View full-size slide

  44. リライング・パーティ(クライアント)側
    ● 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
    ○ 認証情報からユーザを取得する処理を追加する

    View full-size slide

  45. まとめ
    ● 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の理解は必要

    View full-size slide

  46. 参考文献
    ● OAuth徹底入門
    ○ https://amzn.to/2I48EtP
    ● 雰囲気で使わずきちんと理解する!整理してOAuth2.0を使うためのチュートリアル
    ガイド
    ○ https://amzn.to/2TcmLnn
    ● OAuth、OAuth認証、OpenID Connectの違いを整理して理解できる本
    ○ https://authya.booth.pm/items/1550861

    View full-size slide

  47. 謝辞
    資料を公開後、誤っている箇所をご指摘いただきました。
    ありがとうございました。
    @authyasan
    @ritou

    View full-size slide