2024年2月4日日曜日

OpenID Providerを作る)ユーザ認証方式について考える

こんにちは、富士榮です。

いよいよユーザの認証について実装を考え始めているのですが、最大の考慮ポイントはパスワードを使ったユーザの認証を実装するかどうか?です。

その前にこれまでのおさらいです。


問題はパスワード認証を許容するかどうか

モダンな認証基盤を作ろうと思うとパスワードを使った知識認証は極力省きたくなります。しかしながら実際に認証基盤を導入していくと必ず出てくるのが認証画面はアプリ側で実装したい、OpenID Providerへのリダイレクトはさせたくない、という要件です。

もちろんこれは集中的にOpenID Providerでアイデンティティを守る、特にログイン画面をフィッシングから守るという主旨と相入れないものなのですが、一貫したUXを守りたいというアプリ側の意見も一定理解できます。

そのため、OpenID Providerの中にはネイティブアプリからバックエンドで呼び出す認証エンドポイントを独自に実装したりしているケースも存在しますし、安直にOAuth2.0のリソースオーナーパスワードグラントを利用しよう、という話になってしまうケースも存在します。

なお、リソースオーナーパスワードグラントについては明確に注意点が記載されているので、どうしても使わないとダメなケース(主にはシステム移行)以外では採用すべきではありません。

リソースオーナーパスワードクレデンシャルグラントタイプは, リソースオーナーがクライアントと信頼関係にある場合, 例えばリソースオーナーの所有するデバイスOSや特別許可されたアプリケーションなどに適している. 認可サーバーはこのグラントタイプを有効にする際は特に注意するべきである. また他のフローが利用できない場合にのみ許可するべきである.

このグラントタイプは, リソースオーナーのクレデンシャル (通常は対話型入力フォームにて取得するユーザー名とパスワード) を取得できるクライアントに適している. また, 保存済みのクレデンシャルをアクセストークンへ変換できるため, Basic認証やDigest認証のような直接的な認証スキームを利用している既存のクライアントをOAuthへ移行する際にも利用できる.


こう考えると新規でOpenID Providerを作る場合はTokenエンドポイントがサポートするgrant_typeからpasswordは落としてしまっても良さそうではあります。


その場合の考慮点

しかし、安直にパスワード認証をなくしてしまうと何が起きるのか?も考慮しておかないといけません。

先のユースケースのようにネイティブアプリケーションへのバックエンドAPI経由でのインテグレーションをしたいケースへの対応、そしてパスワード以外の認証手段のみしか提供しなかった場合のアカウントリカバリの方式をどうするか?などセットで考えなければならないことが出てきます。

ネイティブアプリへの認証APIの提供

  • ここは個人的な意見としては落としてしまっても良いかとは思いますが、アプリケーションチームとの力関係もあると思うので十分な話し合いや安全性に関する検証が必要な領域です。

リカバリ方法

  • 安全なアカウントリカバリ方法が提供できない場合は、いくらデフォルトの認証手段を強固にしたとしても、そこから突破されるので意味がありません。そのため認証手段を強くする際はリカバリ手段もしっかりと固める必要があります。(最近某C2C取引アプリでdiscoverable credentialが実装される前のWebAuthnが実装された状態からパスキーへ移行したことにより、過去にデバイスにバウンドされた鍵しか登録しなかったユーザがログインできなくなるという事件もありましたので、場合によっては過去の経緯やユーザの状態を含め分析をしないといけません)


今回はせっかく新規で作るのでやっぱりパスキーをデフォルトにしてしまうのが良いのかなぁ、、と思案中です。(ここまでくるとOpenID Connectの仕様のスコープ外なのですが)



0 件のコメント: