🔑

(Ruby) OmniAuth v2.0 メジャーリリースの変更点・アップグレードガイド。OSSコントリビュートチャンスについて

2021/03/17に公開

Rubyにおいて、外部サービスとの認可・認証に広く利用されている OmniAuth 2.0 のメジャーバージョンのリリースが2021年1月12日にありました。

本記事では、RailsでのWebサービス提供者として、OmniAuth Strategy提供者としてキャッチアップした内容をまとめます。

OmniAuth 2.0 変更点およびアップグレードガイド

以下の公式リリースノート、2.0アップグレードガイド(omniauth, devise)を元に記事を書いています。
https://github.com/omniauth/omniauth/releases/tag/v2.0.0
https://github.com/omniauth/omniauth/wiki/Upgrading-to-2.0
https://github.com/heartcombo/devise/wiki/OmniAuth:-Overview

※免責:間違った解釈をしている可能性がありますので、必ず公式情報もご参照ください。

変更点① OmniAuth now defaults to only POST as the allowed request_phase method.

CSRF脆弱性 CVE-2015-9284の対応に伴う変更です。

1系まではサービスプロバイダーのサービス認可画面へリダイレクトするエンドポイントはデフォルトでGET/POSTどちらも有効でしたが、2.0からPOSTのみに変更となりました。

アップグレード時の影響

例えば、Google認証を実装しているWebアプリで、ログイン画面に以下のようなリンクを埋め込んでいる場合、2.0系からGETリクエストは受け付けられなくなるので、対応が必要になります。

https://example.com/users/auth/google

以下のようなメッセージで404エラーとなりました。

Not found. Authentication passthru.

アップグレード時の対応

  • 前提
    • Rails6系、devise で確認した内容 (その他環境については公式ガイドを参照)
    • Google等のStrategy側で omniauth 2系 に対応している、利用を許可している

2021年3月17日現在、devise は 対応Gemがrubygemsにリリースされていないので、masterブランチを指定します。関連PR

gem 'devise', github: 'heartcombo/devise'

Cookpad社が公開している上記CSRF脆弱性対応用のGemを追加します。

gem 'omniauth-rails_csrf_protection'

認可画面URLへのリダイレクトさせるリンクへのアクセス方法をGETからPOSTに変更します。(例 Google)

# リンクの場合
<%= link_to "Sign in with Google", user_google_omniauth_authorize_path, method: :post %>
# ボタンの場合
<%= button_to "Sign in with Google", user_google_omniauth_authorize_path %>

非推奨となりますが脆弱性を許容できるがPOST化が難しい場合、今まで通り以下の設定でGETも利用可能にできます。(config/initializers/omniauth.rb 等で指定)

OmniAuth.config.allowed_request_methods = [:get, :post]

GETを許可すると以下のような警告が表示されるようになります。

[72b2e6e4-764e-4e1d-8e6b-f1f2ae083f32] (google)   You are using GET as an allowed request method for OmniAuth. This may leave
  you open to CSRF attacks. As of v2.0.0, OmniAuth by default allows only POST
  to its own routes. You should review the following resources to guide your
  mitigation:
  https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284
  https://github.com/omniauth/omniauth/issues/960
  https://nvd.nist.gov/vuln/detail/CVE-2015-9284
  https://github.com/omniauth/omniauth/pull/809

  You can ignore this warning by setting:
  OmniAuth.config.silence_get_warning = true

警告を非表示にしたい場合は、以下で非表示にできます。

OmniAuth.config.silence_get_warning = true

変更点② Unhandled Exceptions

options_call, request_call, callback_call, other_phase
において例外が補足されるようになり、例外発生時はデフォルトの設定だと /auth/failureにリダイレクトされます。

関連PR

アップグレード時の影響もしくは対応

  • (影響)アプリ側でエラーハンドリングを独自実装している場合、振る舞い調整が必要になる可能性があります。

変更点③ Provider Namespacing

providerとして指定するStrategyのクラスの検索対象が OmniAuth::Strategies 内に限定されるようになりました。同名定数の曖昧な読み込みを早期に回避できるようになりました。

関連PR

アップグレード時の影響もしくは対応

  • 影響なし。

変更点④ Failure Route

失敗時にリダイレクトパスが OmniAuth.config.path_prefix より Strategy#path_prefix が優先されるようになりました。

例えば、Strategy側のpath_prefixを /external に指定した場合、失敗時のパスは /external/failure になります。

関連PR

アップグレード時の影響もしくは対応

  • (影響)Strategy側のpath_prefixオプションを利用している場合、失敗時のパスが変わります。

変更点⑤ Thread Safety

テスト時に rack-freeze を利用することでスレッドセーフになりました。

関連PR

アップグレード時の影響もしくは対応

  • 影響なし。

変更点⑥ Frozen Strings

fronzen string利用時のエラーが解消されるようになりました。

関連PR
関連PR

アップグレード時の影響もしくは対応

  • 影響なし。

変更点⑦ Relative Root Apps

相対ルートとして指定できるRack環境変数SCRIPT_NAMEがリクエストフェーズで生成されるリクエストURLに含まれるようになりました。コールバックフェーズのURL,失敗時のURLには従来どおり含まれます。

関連PR

アップグレード時の影響もしくは対応

  • (影響)相対ルート SCRIPT_NAME 利用時に、リクエストフェーズのURLが変更になります。
  • (影響)(Strategy提供者向け)Strategy#callback_urlをオーバーライドしている場合、コールバックフェーズのURLに SCRIPT_NAME が冗長になる事象・実装が散見されます。※ ☆OSSコントリビュートチャンスについては後述☆

以上が変更点およびアップグレードガイドの内容です。
ご指摘等、歓迎しております。

OSS コントリビュートチャンスについて

上記で書かせていただいた通り、OmniAuth1系から2系は互換性のない振る舞い変更があるので、既存の多くのStrategy側でも対応が必要な状況になっています。

Rubistの皆さん!今、コントリビュートチャンスが来ています!

著者もメンテしているStrategy以外に、GoogleのOAuth2 Strategyである omniauth-google-oauth2 の既存issueにコメントしてPRを送ったらコントリビュートできました🎉🎉 該当のPR

omniauth-facebook に出したPRは依存関係の定義ミスで 👎 をもらったときは凹みました(&リリース前に止めてもらって感謝)😂
それも勉強になり他のコントリビュートに活かせました。

omniauth-facebook プルリクに👎つけられた

普段、お世話になっていて動作確認できるStrategyを対象に以下PRを出してます。
もしこの投稿がレポジトリオーナーさんに届きましたら、ご確認・問題なければマージいただけると幸いです😁

公開されているOmniAuth StrategyはこちらからRubyGemsで検索ができます。
https://rubygems.org/search?query=omniauth-

比較的軽い変更になると思うので、OSS活動を始めたい方、自分以外の他プロジェクトにコントリビュートしたい方にはよい機会だと思います。貢献できるStrategyを探してみてはいかがでしょうか。

Discussion