私は1つの(SPA)クライアントで構成され、複数のAPIを呼び出し、すべて私の制御下にあるマルチテナントシステムを構築しています。
ユーザー認証はOpenID Connectで行われ、IDとアクセストークンをクライアントに送信します。クライアントはアクセストークンを使用してAPIを呼び出します。
この段階では、APIは認証されたユーザーからリクエストを受け取っていることを認識していますが、そのユーザーが何ができるか、つまり承認の部分を知る必要があります。
すべてのAPIが承認データが保持されているストアを呼び出すというシナリオを回避したいと思います。これはパフォーマンスのボトルネックのように感じられ、すべてのAPIを密結合します。
OpenID Connectサーバーをこの特定のプロジェクトから可能な限り切り離して、ユーザーのIDとAPIスコープのクレームのみを処理したいと思います。したがって、すべての承認関連のクレームをアクセストークン内に配置することは、間違った動きのように見えます。
私は次の解決策を思いつきました:
ユーザーがSPAに移動します
SPAはOpenID Connectサーバーを呼び出し、ID情報を含むアクセストークンを取得します
SPAはこのプロジェクトに固有のカスタムAPIエンドポイントを呼び出し、それを「user-info-api」と呼びます
このAPIは、証明書または共有秘密によって署名されたカスタムJWTトークンを発行します
このカスタムJWTトークンは、後続のすべてのAPIリクエストに追加されます。これには、各APIでユーザー認証を行うために必要なすべての情報が含まれているため、認証ストアへの往復がなくなります。 APIが行う必要があるのは、その署名を確認することだけです。
以下の理由により、このアプローチについての2番目の意見をお願いします。
一般に、ロールベースの認証と言えば、ロールマッピングへの構成可能な権限を持たないようにします。
これを実現する最も簡単な方法は、ロールとまったく同じ権限を付与することです。したがって、認証プロバイダーはトークンを返します
user : ewan
roles : [User, Editor]
アプリには権限があります:
[Authorize(Role=Editor)]
お気づきのように、一般的に次のようなアプリ固有の役割は避けたいと思います。
user : ewan
roles : [MeTube.User, MyFaceSpace.Editor]
OpenID Connectの推奨事項は、アプリのクレームにURLプレフィックスを使用することです
user : ewan
https://www.MyFaceSpace.com/roles : [Editor]
https://www.MeTube.com/roles : [User]
次に、「スコープ」を使用して、アプリケーションごとに正しいクレームのセットを要求できます。
認証サーバーとAPIを制御する場所では、2番目の承認サーバーやマッピングを追加するのではなく、このアプローチを使用することをお勧めします。
OpenID Connectフローには、プロバイダーに2番目に指定されたプロバイダーからの追加のクレームを含めることを可能にするメソッドはないと思います。
できることは、返されたクレームに加えていくつかの独自のクレームを使用して新しいトークンを作成し、今後の呼び出しでこれを使用するようユーザーに要求することです。これは、ASP.Net Webページが行うことであり、トークンを取得しますが、その後、後続の要求の認証に使用される認証Cookieを生成します。
APIでは、ユーザーに2つの認証呼び出しを行わせる必要があるようです。 1つは認証用、もう1つは承認クレーム付きのアプリ固有のトークンを取得するためのものです。