パスキーによる認証を体験

はじめに

2022年12月に Chrome でパスキーが利用できるようになりました。
そのことを伝えるネット記事をいくつか読んだときには、パスキーを使った認証の全体像というか仕組みというかそういうものがいまいちピンと来なかったので、もう少し詳しいことを調べつつデモサイトでその動作を体験してみました。

WebAuthn とパスキー

WebAuthn (Web Authentication)

WebAuthn は認証に関するウェブ標準の1つで、いわゆる「パスワード不要の認証」を実現する FIDO2 認証をウェブブラウザ上で実現するためのものです。

従来のIDとパスワードによる認証では、パスワード(あるいはパスワードのハッシュ)という秘密情報をサービスのサーバに預ける必要がありました。そのため漏洩のリスクがあり、漏洩してしまうと同じパスワードを使う別のサービスでも使われてしまうという問題を抱えています。

WebAuthn による認証は次のような特徴を持っています。

  • 秘密情報はユーザの手元のデバイスで保持する(漏洩のリスクが非常に低い)
  • 認証に使うクレデンシャルはサービスのドメインと紐付けられているのでフィッシングに強い
  • 従来型のログインで必要だったID・パスワードの入力や、ワンタイムパスワードの入力などが不要で、利便性が高い

WebAuthn によるユーザ登録の大まかな流れは以下の通りです。

  1. ウェブブラウザがサーバにユーザIDを送り、登録を要求する
  2. サーバがチャレンジ(検証に利用するランダムな数値列)を生成してブラウザに返す
  3. ブラウザは認証器にチャレンジを渡す
  4. 認証器は鍵ペアの生成承認を得るために、ユーザに生体認証を求める
  5. 生体認証がOKならば、認証器は秘密鍵と公開鍵のペアを生成する
  6. 認証器は秘密鍵を使ってチャレンジに署名し、署名付チャレンジ・公開鍵・クレデンシャルID(秘密鍵に紐付いたID)をウェブブラウザに返す
  7. ウェブブラウザは署名付チャレンジ・公開鍵・クレデンシャルIDをサーバに送る
  8. サーバは公開鍵を使って署名付チャレンジを検証する
  9. チャレンジの検証結果とその他のチェック(ドメインなど)がOKならユーザの公開鍵・クレデンシャルIDをユーザIDに対応付けて保存する

WebAuthn による認証の大まかな流れは以下の通りです。

  1. ウェブブラウザがサーバにユーザIDを送り、チャレンジを要求する
  2. サーバはユーザIDに紐付いたクレデンシャルIDと共にチャレンジをブラウザに返す
  3. ブラウザは認証器にチャレンジ・クレデンシャルIDを渡す
  4. 認証器は秘密鍵の利用承認を得るために、ユーザに生体認証を求める
  5. 生体認証がOKならば、認証器はクレデンシャルIDに対応した秘密鍵を使ってチャレンジに署名してウェブブラウザに返す
  6. ウェブブラウザは署名付チャレンジ・クレデンシャルIDをサーバに返す
  7. サーバは公開鍵を使って署名付チャレンジを検証する
  8. チャレンジの検証結果とその他のチェック(ドメインなど)がOKならログイン成功

重要なのは以下の点です。

  • 秘密鍵はサーバに送られず、ローカルの認証器に保存される
  • 生体認証の情報はサーバに送られず、ローカルの認証器で秘密鍵を利用するときのユーザ確認として利用される

重要な情報はローカルに有り、サーバ側で保存している情報(公開鍵やクレデンシャルID)が漏れたとしても攻撃には利用できない訳です。

パスキー

WebAuthn では基本的にウェブブラウザと認証器は同じ機器で動いていることが想定されていました(スマートフォン内蔵の指紋認証や PC の USB ポートに接続されたセキュリティキーなど)。スマートフォンで WebAuthn のクレデンシャルを生成し、記録したとします。買い替えや紛失でそのスマートフォンが使えなくなったら登録をやり直さなければなりません。また、異なる端末からログインする場合には同じサービスであってもそれぞれの端末で登録する必要がありました。

パスキーは WebAuthn のそういった課題を解決して使い勝手を向上させるための拡張です。

  • ウェブブラウザと認証器が別々の機器であっても動くようにした
  • 複数の認証器でクレデンシャルを同期できるようにした

パスキーによる認証を体験する

https://webauthn.io/ というデモサイトでパスキーによる認証を体験してみます。

登録

ユーザ名を入力して”Register”を押します。

今回はスマートフォンを利用するので「別のデバイス」を選びます。

QR コードが表示されるのでスマートフォンで読み込んで FIDO: で始まる URL にアクセスします。

パスキーの作成について確認されるので「続行」します。

スマートフォン側で生体認証を要求されます。(この画面はスクリーンショットを撮れませんでした)

ここで「このパソコンの情報を保持する」にチェックを入れておくと、認証の際に QR コードの表示(PC側)と読み取り(スマートフォン側)のステップをスキップできます。

これで登録完了です。

認証

登録済のユーザ名を入力して”Authenticate”を押します。

先程登録に使ったスマートフォンを選びます。

スマートフォン側で生体認証を要求されます。(この画面はスクリーンショットを撮れませんでした)

ログイン完了。一旦登録が完了してしまえばログインは非常に簡単です。

ここまでの手順は Linux デスクトップで行いました。
Chrome でパスキーが使えるようになったというリリース情報では Linux 版の Chrome が対応しているのかどうかいまいちハッキリしないところがあったのですが、試してみるとあっさり動きました。

この状態で、たとえば別の Windows PC の Chrome で webauthn.io にアクセスしてスマートフォンを認証器として利用して splout01 で同じ手順でログインできます。

パスキーを利用する際に Bluetooth を使って機器同士の近接をチェックしているので、PC とスマートフォンの両方で Bluetooth が有効になっていないといけません。試しに PC とスマートフォンそれぞれで Bluetooth をオフにしたところ、どちらがオフの場合でも途中で認証失敗となりました。(Bluetooth をオンにするように促される)

おわりに

従来よりも安全でパスワードの煩わしさからも解放されるパスキーには大いに期待しています。
これから対応サービスが増えていくのが楽しみです。

【Google Chrome】検証ツールの小ネタ(レスポンシブ編)

コーディングや開発をする方なら、日頃からGoogleChromeの検証ツールはよく使われていると思います。
今回はレスポンシブデザインを確認する時に、個人的に便利だと思っている検証ツールの小ネタを紹介したいと思います。

レスポンシブモードを有効にする🖥️

右上の「デバイス切り替え」アイコンをクリックします。
ブラウザ表示がレスポンシブ表示に切り替わります。

レスポンシブモードのオプション🛠️

デバイスのフレームを表示

右上の縦の三点リーダーアイコンをクリックして「デバイスのフレームを表示」を選択します。
対応している一部の機種に限りますが、表示しているデバイスのフレームが表示されます。

メディアクエリを表示

右上の縦の三点リーダーアイコンをクリックして「メディアクエリを表示」を選択します。
この機能を有効にすると、サイト上で使用しているメディアクエリを視覚的に表示してくれます。
サイズの指定方法の違いが色ごとにわかりやすく表示されます。

max-width(**px以下)
max-widthとmin-widthを使用(**px以上、**px以下)
オレンジ min-width(**px以上)

スクリーンショットをキャプチャ

表示中のレスポンシブサイズのスクリーンショットを撮影してくれます。
ブラウザ拡張などでスクリーンショットを撮影している方も多いかと思いますが、ブラウザのデフォルト機能だけでスクリーンショットを撮影できるので手軽に使えます。
また「デバイスのフレームを表示」が有効で、フレームが表示されている場合、フレーム込みでスクリーンショットが撮影されるので、撮影後に別アプリなどでモックにはめ込む作業も必要ありません。

表示端末の追加📲

レスポンシブモードでシミュレートできるデバイスの追加も可能です。
ツールバー上部の[サイズ]をクリックしてデバイス一覧を開き、[編集]をクリックします。
好きなデバイスや自分でカスタマイズしたデバイスを追加することもできます。
特殊な環境やサイズのデバイスを追加する際に、非常に便利な機能になっています。

検証ツールは奥が深い…

レスポンシブのデザインやコーディングをする機会は多いと思います。
地味な機能の紹介ばかりですが、少しでも検証ツールの機能を活用して効率よい作業の手助けになればと思います。
そして、検証ツールには他にも数え切れないほどの機能があるので、今後も少しずつ紹介していけたらと思います…🫠

[Javascript] 元のエラーを渡せる Error Cause

ES2022 で Error に cause がオプションとして追加され、再スローするときに元のエラーを渡すことができます。

以下、MDNのドキュメントより。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause

サンプル

fetch でエラーになるサンプルを作りました。


function UserException(message, options) {
	this.message = message;
	this.name = 'UserException';
	this.cause = options.cause;
}

async function test() {
	try {
		const response1 = await fetch('http://example.co.jp/')
			.catch(err => {
				throw new UserException('fetch1回目でエラー', { cause: err });
			});
		const text1 = response1.text();

		const response2 = await fetch('http://example.co.jp/', { method: 'POST', body: text1 })
			.catch(err => {
				throw new UserException('fetch2回目でエラー', { cause: err });
			});
		return response2.json().catch(err => {
			throw new UserException('json()でエラー', { cause: err });
		});
	} catch (err) {
		throw new Error('エラーです', { cause: err } );
	}
}

test().catch(err => {
	console.log(err);
	console.log(err.cause);
})

console.log に出力された内容

fetch2回目でエラーになった場合の Devtools の表示

// Error: エラーです at test (sample:24:9)
// UserException {message: 'fetch2回目でエラー', name: 'UserException', cause: TypeError: Failed to fetch at test (sample:16:27)}

response2.json() で失敗した場合

// UserException {message: 'json()でエラー', name: 'UserException', cause: SyntaxError: Unexpected token 'T', "Text" is not valid JSON}
// SyntaxError: Unexpected token 'T', "Text" is not valid JSON

cause に渡すことで再スローされた先で簡単に元のエラーを受け取ることができました。

エラーの再スロー自体は一般的ですが、ES2022 以前には元のエラーを得る手段が標準で用意されていなかったのが不思議なくらいです。

エラー処理には悩まされることがよくあり、その場で処理することが難しい場合やまとめて処理しても問題ない場合などに使えそうです。

●●●

余談ですが、ブラウザによっては、cause とは別に stack が実装されているようですが、こちらは標準化はされなかったようです。stack という文字から Stack trace 的なものが格納されるのでしょうが、サーバーでの処理と違ってクライアント側なのでデバッグ後の消し忘れによる事故が多そうではあります。

[Solr]Admin UIでフィールドタイプの編集をできるようになった

Solr 9.1.0 から Admin UI でフィールドタイプの定義を編集ができるようになりました。
それ以前はフィールド定義の追加はできるもののフィールドタイプには手を付けることができない状態でした。

上のスナップショットは8.11.0のAdmin UIです。

9.1.0のAdmin UI。
“Manipulate Field Type” というボタンが増えています。このボタンを押すとフィールドタイプを追加するためのコマンドのテンプレートがテキストエリアとして表示されます。

プルダウンを”Delete FieldType Template”に変更したところ。
指定のフィールドタイプを削除するためのコマンドを編集できます。

プルダウンを”Replace FieldType Template”に変更したところ。
指定のフィールドタイプの定義を書き換えることができます。

従来から存在していたフィールドに対する操作が追加のみであったことを考えると、フィールドタイプに対する操作が一気に充実したことになります。

Solr 9.1.0 ではこれ以外にもAdmin UIへの機能追加がいくつかあったので、順次ご紹介していければと思います。

2022年に習得した新しい習慣

2022年も残す所あと僅か。
今年も色々あったと思うのですが、あっと言う間に過ぎ去ろうとしています。

厄年である私が新しい習慣を身につけることは中々ないのですが、珍しく新習慣を会得しました。

それは…。

 

トイレ掃除です。

 

2022年5月からですが、ほぼ毎朝トイレ掃除をしています。
ズボラな私が半年以上続けられるとはちょっとした奇跡かなと思ったりしています。

「トイレの神様」って歌が流行った時期もありましたが、改めて調べてみると存在するようで、「烏枢沙摩明王(うすさまみょうおう)様」というらしいです。

 

それはそれはキレイな女神様がいるんやで〜♪

 

と、聞いたことがあったので、どんな神様かなと期待して調べてみると「烏枢沙摩明王様」というらしく、めちゃくちゃ怖い顔をして、全身火炎に包まれた火の神様のようです。

最初のイメージと違うなと思ったのですが、昔のトイレは伝染病などの感染源になりやすい場所だったので、魔の入口のような考えがあったとのこと。

そのため怖い顔して、炎で浄化して、悪いものから守ってくれている存在として伝えられているようです。

 

私がトイレ掃除を初めたきっかけは、厄年だからだったからかもしれません。
今ではやらないと、落ち着かなくなっています。

 

まだまだトイレ掃除、初級者の私ですが、これからも続けてみようと思います。