(Ruby) OmniAuth v2.0 メジャーリリースの変更点・アップグレードガイド。OSSコントリビュートチャンスについて
Rubyにおいて、外部サービスとの認可・認証に広く利用されている OmniAuth 2.0 のメジャーバージョンのリリースが2021年1月12日にありました。
本記事では、RailsでのWebサービス提供者として、OmniAuth Strategy提供者としてキャッチアップした内容をまとめます。
OmniAuth 2.0 変更点およびアップグレードガイド
以下の公式リリースノート、2.0アップグレードガイド(omniauth, devise)を元に記事を書いています。
※免責:間違った解釈をしている可能性がありますので、必ず公式情報もご参照ください。
変更点① 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
にリダイレクトされます。
アップグレード時の影響もしくは対応
- (影響)アプリ側でエラーハンドリングを独自実装している場合、振る舞い調整が必要になる可能性があります。
変更点③ Provider Namespacing
providerとして指定するStrategyのクラスの検索対象が OmniAuth::Strategies 内に限定されるようになりました。同名定数の曖昧な読み込みを早期に回避できるようになりました。
アップグレード時の影響もしくは対応
- 影響なし。
変更点④ Failure Route
失敗時にリダイレクトパスが OmniAuth.config.path_prefix
より Strategy#path_prefix が優先されるようになりました。
例えば、Strategy側のpath_prefixを /external
に指定した場合、失敗時のパスは /external/failure
になります。
アップグレード時の影響もしくは対応
- (影響)Strategy側のpath_prefixオプションを利用している場合、失敗時のパスが変わります。
変更点⑤ Thread Safety
テスト時に rack-freeze を利用することでスレッドセーフになりました。
アップグレード時の影響もしくは対応
- 影響なし。
変更点⑥ Frozen Strings
fronzen string利用時のエラーが解消されるようになりました。
アップグレード時の影響もしくは対応
- 影響なし。
変更点⑦ Relative Root Apps
相対ルートとして指定できるRack環境変数SCRIPT_NAME
がリクエストフェーズで生成されるリクエストURLに含まれるようになりました。コールバックフェーズのURL,失敗時のURLには従来どおり含まれます。
アップグレード時の影響もしくは対応
- (影響)相対ルート SCRIPT_NAME 利用時に、リクエストフェーズのURLが変更になります。
- (影響)(Strategy提供者向け)
Strategy#callback_url
をオーバーライドしている場合、コールバックフェーズのURLにSCRIPT_NAME
が冗長になる事象・実装が散見されます。※ ☆OSSコントリビュートチャンスについては後述☆- omniauth-google-oauth2 https://github.com/zquestz/omniauth-google-oauth2/issues/401
以上が変更点およびアップグレードガイドの内容です。
ご指摘等、歓迎しております。
OSS コントリビュートチャンスについて
上記で書かせていただいた通り、OmniAuth1系から2系は互換性のない振る舞い変更があるので、既存の多くのStrategy側でも対応が必要な状況になっています。
Rubistの皆さん!今、コントリビュートチャンスが来ています!
- 参考 プルリク、イシュー
- omniauth-github PR https://github.com/omniauth/omniauth-github/pull/95
- omniauth-salesforce issue https://github.com/realdoug/omniauth-salesforce/issues/31
著者もメンテしているStrategy以外に、GoogleのOAuth2 Strategyである omniauth-google-oauth2 の既存issueにコメントしてPRを送ったらコントリビュートできました🎉🎉 該当のPR
omniauth-facebook に出したPRは依存関係の定義ミスで 👎 をもらったときは凹みました(&リリース前に止めてもらって感謝)😂
それも勉強になり他のコントリビュートに活かせました。
普段、お世話になっていて動作確認できるStrategyを対象に以下PRを出してます。
もしこの投稿がレポジトリオーナーさんに届きましたら、ご確認・問題なければマージいただけると幸いです😁
- ginjo/omniauth-slack
- simi/omniauth-facebook
- jetrockets/omniauth-instagram-graph
- kazasiki/omniauth-line
- zaikoflow/omniauth-thebase
- kkanazaw/omniauth-freee
公開されているOmniAuth StrategyはこちらからRubyGemsで検索ができます。
比較的軽い変更になると思うので、OSS活動を始めたい方、自分以外の他プロジェクトにコントリビュートしたい方にはよい機会だと思います。貢献できるStrategyを探してみてはいかがでしょうか。
Discussion