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

Railsアプリにパスワードレス認証を導入した知見

 Railsアプリにパスワードレス認証を導入した知見

Kaigi on Rails 2023 10.28(Sat.)
虎の穴ラボ 河野裕隆
RailsアプリにPasskeyによる認証を導入した際の話です。

https://kaigionrails.org/2023/

虎の穴ラボ株式会社

October 30, 2023
Tweet

More Decks by 虎の穴ラボ株式会社

Other Decks in Technology

Transcript

  1. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. Railsアプリにパスワードレス認証を導入した知見

    虎の穴ラボ 河野 裕隆 Kaigi on Rails 2023 10.28 #kaigionrails #kaigionrailsA T O R A N O A N A L a b
  2. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. 好きなもの

    • VOCALOID(初音ミク) • 謎解き、クイズ 今期おすすめアニメ • SHY 自己紹介 河野裕隆 • 2019/08入社 • 新規開発チーム ◦ クリエイティア他 虎の穴ラボへの入社理由 • スキルを高めあえる仲間がほしい • ユーザーに近い仕事がしたい 2
  3. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    パスキーとはなにか • Rails アプリへのパスキー導入 • 導入時の注意点など 話すこと 5
  4. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    詳細な実装方法 話さないこと 6 聞いてほしい人 • パスキーについて知りたい人 • パスキーをアプリに入れたい人
  5. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    パスワードを使わない • 端末(スマホ/PC等)の認証情報で認証する ※パスキーは通称で、正式な仕様名ではない パスキーとは - サービスサイド 8
  6. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    Creatia(ファンクラブサイト)-iPhone SE2 パスキーとは - 実際の挙動 9 Chrome 指紋で認証
  7. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    パスワードを覚える必要がない • 端末の所持と生体認証の組み合わせ ◦ 非常にセキュア ◦ ユーザーも簡単 セキュアでユーザビリティが高い!!! パスキーのメリット 10
  8. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    WebAuthnの拡張 ◦ Webで認証器を用いての認証 ▪ 認証器:スマホ、Yubikeyなど • FIDO 2(Fast Identity Online)の構成要素 ◦ オンライン認証をスムーズにする! パスキーとは - エンジニアサイド 11
  9. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    Googleのチュートリアル ◦ https://developers.google.com/codelabs/webauthn-reauth?hl=ja#1 ◦ フロントの実装のみ • RFC ◦ https://www.w3.org/TR/webauthn/ パスキーとは - 仕様等の参考情報 12
  10. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    登録 ◦ 公開鍵を生成、登録する • 認証 ◦ 秘密鍵で認証する ※公開鍵暗号方式と同じイメージ パスキーの導入 - 大まかな処理内容 14
  11. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. 1.

    サーバー側にアクセス 2. ランダムに生成したトークンを返却 3. サーバーのトークンをもとにデバイス側でトークン を生成(navigator.credentials.create()) 4. デバイス側のトークンをサーバー側に保存 パスキーの導入 - 登録 16
  12. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. パスキーの導入

    - 登録 17 出典: https://developer.mozilla.org/ja/docs/Web/API/Web_Authentication_API

  13. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. 1.

    サーバー側にアクセス 2. ランダムに生成したトークンを返却 3. サーバーのトークンから端末でトークンを生成 (navigator.credentials.create()) 4. デバイス側のトークンをサーバー側に保存 パスキーの導入 - 登録フロー 18
  14. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. 1.

    サーバー側にアクセス 2. ランダムに生成したトークンを返却←細かい仕様あ り =>Gemを使うことで解消 パスキーの導入 - 登録フロー 19
  15. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. パスキーの導入

    - トークンの仕様 20 • challenge
 ◦ 署名の検証に使われるランダムな値(チャレンジレスポンス) 
 ◦ リプライアタックの防御が必要 
 ◦ サーバーサイドなど信頼できる環境で生成すること(MUST) 
 ◦ 最終的にクライアントの動作に依存せず一致が確かめられること 
 ▪ そのため、一連の操作が完了するまで何らかの形で保持が必要(SHOULD) 
 ◦ 推測不可能なものにすること(MUST)、少なくとも16byte以上(SHOULD) 
 • rp
 ◦ 認証サーバーの情報(アプリ名とか) 
 • user
 ◦ ユーザーIDや名前、表示名など 
 • attestation
 ◦ 認証器の正当性をチェックする方法の選択 
 ▪ none: 全くしない
 ▪ indirect: チェックするが認証器が生成したものでなくても良い 
 ▪ direct: 直接認証器から生成されたattestationをチェックする 
 ◦ none以外ではユーザーの同意が必要
  16. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. パスキーの導入

    - Railsでの導入 21 https://github.com/cedarcode/webauthn-ruby `$ gem install webauthn` 証明や署名の検証、 CBORのパースなどすべてやってくれる
  17. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. パスキーの導入

    - Gemを使う利点 22 開発者がRFCに沿った実装を • 確実に • セキュアに 進めるのは難しい =>信頼できるライブラリを利用する
  18. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. 1.

    `config/initializers/webauthn.rb`に設定を書く サービス名、URLくらいでOK 2. `WebAuthn::Credential.options_for_create`を 呼ぶ パスキーの導入 - webauthn(Gem)の利用 23
  19. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. #

    一意のキーを発行 if !user.webauthn_id user.update!(webauthn_id: WebAuthn.generate_user_id) end # 登録用のトークン発行 options = WebAuthn::Credential.options_for_create( user: { id: user.webauthn_id, name: user.name }, exclude: user.credentials.map { |c| c.webauthn_id } ) パスキーの導入 - webauthn(Gem)の利用 - options_for_create 24
  20. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. 1.

    サーバー側にアクセス 2. ランダムに生成したトークンを返却 3. サーバーのトークンから端末でトークンを生成 (navigator.credentials.create()) 4. デバイス側のトークンをサーバー側に保存 パスキーの導入 - 登録フロー 25
  21. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. パスキーの導入

    - 登録 - フロントのコールバック # 認証情報を生成(CBORを解析) webauthn_credential = WebAuthn::Credential.from_create(params[:publicKeyCreden tial]) # 証明書を検証 webauthn_credential.verify(session[:creation_challenge]) # ユーザーに紐づけて登録 user.credentials.create!( webauthn_id: webauthn_credential.id, public_key: webauthn_credential.public_key, sign_count: webauthn_credential.sign_count ) 26
  22. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. 1.

    サーバー側にアクセス 2. パスキーのトークン情報を返却 3. 署名済みオブジェクトを生成 (navigator.credentials.get()) 4. サーバー側に送って検証する パスキーの導入 - 認証フロー 28
  23. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. パスキーの導入

    - 登録 29 出典: https://developer.mozilla.org/ja/docs/Web/API/Web_Authentication_API

  24. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. 1.

    サーバー側にアクセス 2. パスキーのトークン情報を返却 3. 署名済みオブジェクトを生成 (navigator.credentials.get()) 4. サーバー側に送って検証する パスキーの導入 - 認証フロー 30
  25. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. #

    対象ユーザーを取得 webauthn_credential = WebAuthn::Credential.from_get(params[:publicKeyCredentia l]) user_credential = user.credentials.find_by(webauthn_id: webauthn_credential.id) # 検証 webauthn_credential.verify( session[:authentication_challenge], public_key: user_credential.public_key, sign_count: user_credential.sign_count ) パスキーの導入 - 認証 - 認証情報の検証 31
  26. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    使えるかチェックする • 登録/認証をpostする パスキーの導入 - フロント側の対応 33
  27. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. https://github.com/github/webauthn-json

    CDNやDLして利用 パスキーの導入 - ライブラリ 34
  28. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. //

    登録時 認証情報の作成 webauthnJSON.create({publicKey:サーバーで生成したoption}); // 認証時 認証情報の取得 webauthnJSON.get({publicKey:サーバーで生成したoption}); 基本的にはこれだけ パスキーの導入 - フロント側の実装 35
  29. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. パラメータ名がWebAuthnのLevelにより切り替わっ

    ている userHandle = user.idなど・・・ パスキーの導入 - パラメータ名 37
  30. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. iOSでは必ずユーザー操作を挟む必要がある

    󰢃NG ログインボタンを押す→トークン取得→navigator.credentials.get()→トーク ン検証→ログイン 󰢏OK ログインボタンを押す→トークン取得→ダイアログなどに確認ボタンを出して押 す→navigator.credentials.get()→トークン検証→ログイン 具体的には一回認証をキャンセルして再度開くパターン パスキーの導入 - iOSでの挙動 38
  31. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. •

    ライブラリを使えば少ない工数で実装可能 • ブラウザ/OSの対応/実装状況に左右される • 拡張されている仕様なので都度最新をチェック まとめ 39
  32. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved. まとめ

    より詳しい解説はブログで! 「虎の穴開発室ブログ WebAuthn導入」で【検索】 https://toranoana-lab.hatenablog.com/entry/2023/06/26/120000 40