パスキー認証 - LINE FIDO2サーバーで体験(Windows&スマホ編)
概要
パスワードレス認証として話題のパスキー。
パスキー認証をまず体験しAPI通信の内容を見てみて少しずつ理解してくための手順。
実際にパスキーで認証可能なサービス
□ 実際のサービスで体験したい場合は以下のアプリで体験できる。
アカウントを登録後、アカウント設定画面からパスキーを登録しログアウト。
ログイン時にパスキー認証でログインができる。
□ TikTokのアプリ https://www.tiktok.com/ja-JP/
□ ニンテンドーアカウント https://www.nintendo.co.jp/support/nintendo_account/passkey/index.html
LINE FIDO2サーバーを体験
□ パスキーの認証がどのように実現されているか理解するために、実装イメージを確認。
□ オープンソースとして公開されているLINE FIDO2-Serverを利用し、通信の内容を確認。
□ その後にシーケンス図を確認することで理解を深める。
環境
□ WindowsOSのPCを利用
□ スマホとPCは同じネットワークに繋がっている(例:同じwifiに繋がっている)
□ (参考)本記事で利用した環境
□ DockerDesktop: 4.26.1 (131620), Engine: 24.0.7
※ DockerDesktop利用できない場合、Rancher Desktop利用でもOK。
※ Docker Desktopは条件に該当した場合のみ無料で利用できる。
有償条件に該当する企業に所属している場合でDocker Desktopを使用したい場合は、
自己学習として自宅のPCで実行することをおすすめする。
□ PC: Windows 11 Home
□ スマホ: iPhone(iOS17.1.2)
□ 使用するもの:LINE FIDO2-Server
オープンソースとして公開されているLINE FIDO2-Serverを利用し、パスキー認証を体験する。
LINE Security R&Dチームは、FIDO2をより広く普及し、より良いソフトウェアに成長させるため、LINE FIDO2-Serverをオープンソースとして公開することにしました。このような活動が、最終的にFIDOエコシステムの発展に貢献すると期待しています。
私たちが公開したオープンソースのGitHubリポジトリーは以下のとおりです。
https://github.com/line/line-fido2-server
手順.WindowsOSでLINE FIDO2サーバーを試す
1.レポジトリのクローン
□ 任意のディレクトリで、work_line_fido
の名前でフォルダを作成する
□ Visual Studio Codeで作成したwork_line_fido
フォルダを開く。
□ Windowsの場合に実行
ctrlキー
と@キー
でTERMINALを開く
※Githubからpullしたファイルの改行コードが変わってしまうとDockerのコンテナを起動できない問題があるため、一時的に下記をターミナルで実行する。
git config --global core.autocrlf input
□ GiHubからクローンする
terminal上で下記を実行
git clone https://github.com/line/line-fido2-server.git
□ (参考)line-fido2-serverのレポジトリ
2.Dockerコンテナを起動
□ Visual Studio Codeでline-fido2-server
のフォルダを開く
□ ctrlキー
と@キー
でTERMINALを開く
terminal上で下記を順番に実行
docker build -t build-image .
docker-compose build
docker-compose up -d
※サーバーが起動するまで時間がかかる可能性あり。
サーバー起動したかはdocker-compose logs rpやdocker-compose logs fido2でログから分かる。
※もし …省略failed to fetch anonymous token…省略
みたいなエラーが出たら、以下を実行後にdocker build -t build-image .
を再実行する。
# windowsの場合(Powershellの場合)
set DOCKER_BUILDKIT=0
set COMPOSE_DOCKER_CLI_BUILD=0
# docker buildの再実行
docker build -t build-image .
※それでもerrorが出る場合は、docker loginを行なう。
docker login
# その後はDocker Hub(https://hub.docker.com)に登録してあるユーザーとパスワードを入力しEnter
# ログインできたら、docker buildの再実行
docker build -t build-image .
3.立ち上がった各サーバーを確認する
URL | 説明 | 用途 | API仕様書 |
---|---|---|---|
http://localhost:8080 | FIDO2 RP SERVER REST API | RP側のサーバー(クライアントがアクセスするサーバー) | http://localhost:8080/swagger-ui.html#/ |
http://localhost:8081 | FIDO2 SERVER REST API | 署名を検証するサーバー | http://localhost:8081/swagger-ui.html#/ |
4.RPサーバーにアクセスしてみる
※ 指紋認証などが無いPCの場合でもPINコード入力で確認できる。
□ http://localhost:8080/ にアクセスする
□ xxxxxx@gmail.com
など任意の値をUser NameとDisplayNameに入力する。
□ PC内蔵の認証機器ではなく、YubiKeyなど含め外部デバイスで認証を行う場合は「On roaming (cross-platform) authenticator」を選択する。
※該当する場合のみ選択。
□ 通信の状態を確認するため、fnキーとF12キーを押して、開発者コンソールを開く。
□ Networkタブを選択し、Preserve Logのチェックボックスにチェックを入れる。
□ ALLが選択されていることを確認する。
□ Registerタブを押下する (パスキー登録)
□ /attestation/options
APIが呼び出されていることが開発者コンソールから確認できる。
□ 認証のモーダルが表示されること
□ 指紋をかざしOKの場合モーダルが表示される
□ モーダルのOKボタンを押下すると、/attestation/result
APIが呼び出されていることが確認できる。
□ リクエストパラメーターはpayload
タブから確認できる
□ レスポンスデータはPreview
タブから確認できる
□ 青色のAuthenticateボタン
を押下する (パスキー認証)
□ パスキーを使用してサインインするかを聞かれる
□ /assertion/options
APIが呼び出されていることが開発者コンソールから確認できる。
□ リストから認証したいユーザーを選択し「次へ」ボタンを押下
□ 指紋をかざしOKの場合、/assertion/result
APIが呼び出されていることが確認できる。
□ WindowsOSでのパスキー体験に必要な手順はここで終わりです。
※ 手順5以降はhttps化やスマホからのアクセスに必要な手順であり、必要な場合に実施してください。
(参考)シーケンスを確認してみる
□ line-fido2-serverが公開しているシーケンスの配置場所
□ 補足:開発者コンソールで確認した通信部分は画像の赤枠部分である。
5.h2-consoleへアクセスできるかを確認
h2-consoleはH2インメモリデータベースで簡易的にサーバーが立ち上がっている間だけデータを保存しておける。
□ http://localhost:8081/h2-console へアクセス
JDBC URL:にはjdbc:h2:mem:userdb;
を入力しconnect。
□ No suitable driver foundエラーになるため、コードを修正する。
https://github.com/line/line-fido2-server のREADME.mdの記載を参考に、implementation('org.zalando:logbook-spring-boot-starter:1.8.1')
をコメントアウトする。
<修正対象ファイル>
-
/line-fido2-server/spring-boot-starter/line-fido2-spring-boot-demo/build.gradle
-
/line-fido2-server/server/build.gradle
// implementation('org.zalando:logbook-spring-boot-starter:1.8.1')
□ 下記を順番に実行
docker-compose down
docker build -t build-image .
docker-compose build
docker-compose up -d
※サーバーが起動するまで時間がかかる可能性あり。
サーバー起動したかはdocker-compose logs rp
やdocker-compose logs fido2
でログから分かる。
□ 再度 http://localhost:8081/h2-console へアクセス
JDBC URL:にはjdbc:h2:mem:userdb;
を入力しconnect。
下記が表示されていることを確認する。
(参考) SELECT * FROM RPなどSQLでデータを参照できる。
手順.ローカルでLINE FIDO2サーバーをhttps化する
6.ループバックアドレスのエイリアスを追加する
□ powershellを管理者として実行する
□ ループバックアドレスのエイリアスを追加
https化の前にrpとfido2のdockerコンテナを同じportで立ち上げるようにするためです。
netsh interface ip add address name="Loopback Pseudo-Interface 1" addr=127.0.0.2 mask=255.255.255.255
□ ループバックの設定が追加されているかを確認する
netsh interface ip show addresses
□ ファイルC:\Windows\System32\drivers\etc\
の設定を変更する
下記を参考にドメイン名を127.0.0.1と127.0.0.2に指定してください
127.0.0.1 localhost
127.0.0.2 localhost
127.0.0.1 fido2.exampletthoge.com # fido2サーバー用
127.0.0.2 exampletthoge.com # rpサーバー用
これでlocalhostに127.0.0.2でもアクセスできるようになります。
□ (参考) ループバックの追加設定の削除は以下を実行
netsh interface ip delete address "Loopback Pseudo-Interface 1" addr=127.0.0.2
□ docker-compose.ymlを変更
/line-fido2-server/docker-compose.yml
のportsを下記に変更し、docker-compose up -d
を実行。
~略~
ports:
- "127.0.0.2:8080:8080"
~略~
ports:
- "127.0.0.1:8080:8081"
変更後の全体は以下。
version : "3.8"
services:
build:
container_name: build-image
image: build-image:latest
build:
context: .
dockerfile: ./Dockerfile
rp:
container_name: rp-server
image: rp:latest
build:
context: .
dockerfile: ./rpserver/Dockerfile
ports:
- "127.0.0.2:8080:8080"
restart: always
fido2:
container_name: fido2-server
image: fido2:latest
build:
context: .
dockerfile: ./server/Dockerfile
ports:
- "127.0.0.1:8080:8081"
restart: always
□ httpとドメインでアクセスできるかを確認する。
※この時点ではhttps
ではなく、まだhttp
です。
http://exampletthoge.com:8080
http://fido2.exampletthoge.com:8080
※ DockerDesktopではなくRancher Desktop環境を利用している場合、http://fido2.exampletthoge.com:8080
のみアクセスができることを確認できればOK。
Rancher Desktop環境の場合は127.0.0.2:8080にホスト環境のブラウザから接続が上手く行かない。
Rancher Desktop環境でも後続のhttps化を行なえRPサーバーにアクセスできるので、http://fido2.exampletthoge.com:8080
にアクセスできることを確認できたら次に進む。
7.HTTPS化のためのオレオレ証明書を生成する
この手順7はpowershellで実行する。
オレオレ証明書(ルート証明書とサーバー証明書)を生成する手順です。
□ 自分のPCのIPアドレスを下記を参考に調べる
windowsの設定画面の「ネットワークとインターネット」から接続しているネットワークをクリック。
IPv4アドレスの値を確認する。
□ Chocolateyをinstallする
Chocolateyはnpmのように簡単にWindowsにソフトを入れられるツール。
Chocolateyでmkcertをinstallするために利用する。
powershellを管理者として実行して下記を貼り付け。
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
このコマンドは https://chocolatey.org/install の下記画像のコマンドをCopyしたものです。
□ インストールの確認
choco -vコマンドを実行し、バージョンが表示されればOK
□ mkcertのインストール
powershellを管理者として実行して下記を貼り付け。
choco install mkcert
(参考)
□ ローカル認証局(CA)のインストール
# ローカル認証局用のディレクトリを任意の場所で作成 ※作成は必須ではありません。
cd
mkdir mkcert
cd mkcert
# ローカル認証局のインストール(mkcert install)
mkcert install
□ サーバー証明書と秘密鍵を作成
# ※サーバー証明書, 秘密鍵用のディレクトリを作成 ※作成は必須ではありません。
mkdir mkcert/ssl
cd mkcert/ssl
# サーバー証明書と秘密鍵を作成1(mkcert rpドメイン名 自分のPCのIPアドレス ループバックアドレスを指定)
# ※自分のPCのIPアドレスに置き換えて実行すること
mkcert exampletthoge.com 192.168.0.7 127.0.0.2
# サーバー証明書と秘密鍵を作成2(mkcert fido2ドメイン名 自分のPCのIPアドレス ループバックアドレスを指定)
# ※自分のPCのIPアドレスに置き換えて実行すること
mkcert fido2.exampletthoge.com 192.168.0.7 127.0.0.1
□ トラストストアにローカル認証局(CA)をインストール(mkcert -install)
mkcert -install
□ モーダルが表示されるので「はい」をクリックする。
□ インストールされたルート証明書を確認する。
□ タスクバーから検索してユーザー証明書を開く。
□ 信頼されたルート証明機関を開く。
□ 発行先が「mkcert」始まりの証明書があることを確認する。
もし見つからない場合は、一度ユーザー証明書を閉じてもう一度開き直して確認する。
8.rpとfido2サーバーのhttps化
まず/line-fido2-server/docker-compose.yml
を変更する。
□ nginxコンテナの定義をdocker-compose.ymlに追加する。
~略~
nginx:
image: nginx:alpine
restart: always
volumes: # ローカルPCのディレクトリ:コンテナの中のディレクトリ
- ./nginx:/etc/nginx
- ./selfcert:/etc/cert/
ports:
- 80:80
- 443:443
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
app_net:
ipv4_address: 172.30.0.4
~略~
□ networksの定義をdocker-compose.ymlに追加
~略~
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.30.0.0/24 # コンテナのIPアドレスを指定するために設定
~略~
□ rpとfido2にnetworkとIPアドレスの指定をdocker-compose.ymlに追加
~略~
networks:
app_net:
ipv4_address: 172.30.0.2 # コンテナのIPアドレスを指定する
~略~
networks:
app_net:
ipv4_address: 172.30.0.3 # コンテナのIPアドレスを指定する
□ 変更後の全体は以下となる。
# /line-fido2-server/docker-compose.yml
version : "3.8"
services:
build:
container_name: build-image
image: build-image:latest
build:
context: .
dockerfile: ./Dockerfile
rp:
container_name: rp-server
image: rp:latest
build:
context: .
dockerfile: ./rpserver/Dockerfile
ports:
- "127.0.0.2:8080:8080"
restart: always
networks:
app_net:
ipv4_address: 172.30.0.2 # コンテナのIPアドレスを指定する
fido2:
container_name: fido2-server
image: fido2:latest
build:
context: .
dockerfile: ./server/Dockerfile
ports:
- "127.0.0.1:8080:8081"
restart: always
networks:
app_net:
ipv4_address: 172.30.0.3 # コンテナのIPアドレスを指定する
nginx:
image: nginx:alpine
restart: always
volumes: # ローカルPCのディレクトリ:コンテナの中のディレクトリ
- ./nginx:/etc/nginx
- ./selfcert:/etc/cert/
ports:
- 80:80
- 443:443
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
app_net:
ipv4_address: 172.30.0.4
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.30.0.0/24 # コンテナのIPアドレスを指定するために設定
□ 手順7で作成したサーバー証明書と秘密鍵を配置する用のselfcertフォルダを作成
/line-fido2-server/selfcert/
□ 手順7で作成したmkcert/ssl
フォルダ内のサーバー証明書と秘密鍵をコピーして/line-fido2-server/selfcert/
に配置する
□ nginxフォルダを作成
/line-fido2-server/nginx/
□ nginxフォルダの中にnginx.conf
ファイルを空ファイルで作成する。
/line-fido2-server/nginx/nginx.conf
□ nginx.confの中身を下記のように記載する
events {
worker_connections 16;
}
http {
server {
listen 443 ssl;
ssl_certificate /etc/cert/exampletthoge.com+2.pem;
ssl_certificate_key /etc/cert/exampletthoge.com+2-key.pem;
server_name exampletthoge.com;
location / {
proxy_pass http://172.30.0.2:8080/; # rpコンテナのipアドレス:port
proxy_redirect off;
}
}
server {
listen 443 ssl;
ssl_certificate /etc/cert/fido2.exampletthoge.com+2.pem;
ssl_certificate_key /etc/cert/fido2.exampletthoge.com+2-key.pem;
server_name fido2.exampletthoge.com;
location / {
proxy_pass http://172.30.0.3:8081/; # fido2コンテナのipアドレス:port
proxy_redirect off;
}
}
}
□ 一旦httpsで起動が成功するかを確認する。
下記を順番に実行。
docker-compose down
docker build -t build-image .
docker-compose build
docker-compose up -d
※サーバーが起動するまで時間がかかる可能性あり。
サーバー起動したかはdocker-compose logs rp
やdocker-compose logs fido2
でログから分かる。
□ https://exampletthoge.com にアクセスアクセスできることを確認
□ https://fido2.exampletthoge.com にアクセスできることを確認
※ この時点ではhttpsで起動はするがRPサーバーの設定の変更をしていないのでパスキー登録ができない。
9.RPサーバーの設定変更
□ application-docker.ymlをドメイン名に変更
ファイル: /line-fido2-server/rpserver/src/main/resources/application-docker.yml
rp.id, rp.origin, rp.port, conformance.urlの値を下記のように変更する。
# /line-fido2-server/rpserver/src/main/resources/application-docker.yml
# 変更後
spring:
profiles:
active: docker
resources:
chain:
cache: false
fido2:
rp:
id: exampletthoge.com
origin: exampletthoge.com
port: 443
conformance:
url: https://exampletthoge.com
logging:
level:
org.springframework.web: DEBUG
org.hibernate: DEBUG
com.linecorp.line: DEBUG
fido2-server:
host: fido2
□ rpサーバーのAdapterController.javaを変更
※これはローカルでスマホを繋げてパスキー体験してみるための変更です。本来はチェック処理をコメントアウトすべきではないです。
ファイルパス:
/line-fido2-server/rpserver/src/main/java/com/linecorp/line/auth/fido/fido2/rpserver/controller/AdapterController.java
・ append(scheme)の記述をappend("https")に変更
AdapterController.java内の2箇所とも変更する。
StringBuilder builder = new StringBuilder()
- .append(scheme)
+ .append("https")
・ rpPortのチェックをコメント化する
AdapterController.java内の2箇所とも変更する。
- if (!StringUtils.isEmpty(rpPort)) {
- builder.append(":")
- .append(rpPort);
- }
+ // if (!StringUtils.isEmpty(rpPort)) {
+ // builder.append(":")
+ // .append(rpPort);
+ // }
□ AuthenticatorTransport.javaにhybrid
を追加する。
ファイルパス:
/line-fido2-server/common/src/main/java/com/linecorp/line/auth/fido/fido2/common/AuthenticatorTransport.java
- INTERNAL("internal");
+ INTERNAL("internal"),
+ HYBRID("hybrid");
□ dockerを起動する。
・ 下記を実行。
docker-compose down
docker build -t build-image .
docker-compose build
docker-compose up -d
※サーバーが起動するまで時間がかかる可能性あり。
サーバー起動したかはdocker-compose logs rp
やdocker-compose logs fido2
でログから分かる。
10.RP IDの登録
□ http://fido2.exampletthoge.com:8080/h2-console へアクセス
JDBC URL:にはjdbc:h2:mem:userdb;
を入力しconnect。
□ 入っている値を確認する
SELECT * FROM RP
□ RPのドメインをRP IDとして登録する。
INSERT INTO RP(ID, NAME, ICON)VALUES('exampletthoge.com', 'example1', null);
□ 動作確認する (https://exampletthoge.com/)
User nameとDisplay nameを入力してRegsiter、Authenticateができるかを確認する。
□ パスキー登録
□ パスキー認証
手順.スマホからアクセスできるようにする
前提:手順.ローカルでLINE FIDO2サーバーをhttps化するが終わっていること。
11.squidのinstall
□ squidのdownload
サイト(https://squid.diladele.com/)より「SQUID FOR WINDOWS」をクリックしてdownload
□ 参考: 公式サイト(http://www.squid-cache.org/Versions/)
公式サイトより、上記ダウンロードサイトに飛べます。
binary package of Squidをクリック > windowsを選択すると上記ダウンロードサイトへのURLの記載がある
□ squidのinsatall
ヴィザードに従ってinstallする。
□ タスクバー検索またはデスクトップから「Squid Server Tray」をクリックする
□ タスクトレーにSquidアプリが表示される
□ アイコンクリックでstartやstopの選択モーダルを表示できる
12.squid.confの設定を変更
C:\Squid\etc\squid\squid.conf
をVisualStudioCodeで開く。
□ 以下を新規追加
#
# Recommended minimum configuration:
#
visible_hostname UNKNOWN # <--追加: ホスト名の秘匿
hosts_file C:/Windows/System32/drivers/etc/hosts # <--追加:参照するhostsファイル
※C:\Windows\System32\drivers\etc\
ではなくC:/Windows/System32/drivers/etc/hosts
を記載する。
□ acl lan src
の行を追加
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
acl lan src exampletthoge.com # <--追加: RPのドメイン名
acl lan src 192.168.0.7 # <--追加:自分のPCのIPアドレス
□ http_access deny to_localhost
をコメント化する。
# http_access deny to_localhost # <-- コメント化
□ タスクバーよりsquidを起動
13.iPhoneのwifiの設定を変更する
□ wifiの設定画面を開き、「自動」になっているプロキシの構成を「手動」にする。
サーバー: 192.168.0.7など自分のPCのIPアドレスを入力する
ポート: 3128
※windowsでsquidが立ち上がっているport
14.スマホから動作確認を行う
□ スマホから https://exampletthoge.com/ にアクセスする。
□ スマホ側に残っているパスキーの情報を確認
スマホの設定画面を開き、パスワードで検索
exampletthoge.comの欄を押下すると、どのUser nameで登録したかがわかる。
事後処理
□ Dockerコンテナを終了する
docker compose down
□ Gitの設定を戻しておく
Gitの改行コードの取り扱いの設定です。手順1でデフォルトのtrueからinputに変更していた。
inputのままがよければ実行しなくてもOK。
□ terminal上で下記を実行。
git config --global core.autocrlf true
□ squidを停止する(利用した場合)
□ iPhoneのwifiの設定のプロキシを構成を「自動」に戻す
□ ループバックアドレスを追加していた場合、削除する。
netsh interface ip delete address "Loopback Pseudo-Interface 1" addr=127.0.0.2
□ 発行したルート証明書の削除
ユーザー証明書管理の「信頼されたルート証明機関」から発行先が「mkcert」始まりの証明書を削除する。
今回のソースコード
□ マスターのレポジトリから変更したソースコードの差分一覧は以下を参照
macOS&スマホ編はこちら
Discussion