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

    View full-size slide

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

    View full-size slide

  3. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    改めまして
    パスキーってなんだろう?
    3

    View full-size slide

  4. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    自分のサービスに
    パスキーを入れるのって
    大変なの?
    4

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  7. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    パスキーってなんだろう?
    7

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  12. 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

    View full-size slide

  13. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    自分のサービスに
    パスキーを入れるのって
    大変なの?
    13

    View full-size slide

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

    View full-size slide

  15. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    登録処理
    15

    View full-size slide

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

    View full-size slide

  17. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    パスキーの導入 - 登録
    17 出典: https://developer.mozilla.org/ja/docs/Web/API/Web_Authentication_API


    View full-size slide

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

    View full-size slide

  19. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    1. サーバー側にアクセス
    2. ランダムに生成したトークンを返却←細かい仕様あ

    =>Gemを使うことで解消
    パスキーの導入 - 登録フロー
    19

    View full-size slide

  20. 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以外ではユーザーの同意が必要

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  23. 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

    View full-size slide

  24. 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

    View full-size slide

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

    View full-size slide

  26. 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

    View full-size slide

  27. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    認証処理
    27

    View full-size slide

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

    View full-size slide

  29. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    パスキーの導入 - 登録
    29 出典: https://developer.mozilla.org/ja/docs/Web/API/Web_Authentication_API


    View full-size slide

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

    View full-size slide

  31. 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

    View full-size slide

  32. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    フロント側処理
    32

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  36. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    導入時の注意点
    ハマったポイント
    36

    View full-size slide

  37. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    パラメータ名がWebAuthnのLevelにより切り替わっ
    ている
    userHandle = user.idなど・・・
    パスキーの導入 - パラメータ名
    37

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  40. Copyright (C) 2022 Toranoana Lab Inc. All Rights Reserved.
    まとめ
    より詳しい解説はブログで!
    「虎の穴開発室ブログ WebAuthn導入」で【検索】
    https://toranoana-lab.hatenablog.com/entry/2023/06/26/120000
    40

    View full-size slide