AuthorizingRealm
より具体的には、テンプレートメソッドを宣言し、返すオブジェクトとオブジェクトをそれぞれ宣言するカスタムをdoGetAuthenticationInfo()
実装doGetAuthorizationInfo()
しAuthenticationInfo
ていることがわかりますAuthorizationInfo
。
ただし、doGetAuthenticationInfo() で AuthenticationInfo (JPA エンティティ) のデータを取得すると、必要な AuthorizationInfo が既にあることがわかります。残念ながら、このデータに固執する良い方法はないようです。そのため、承認フィルターが最終的にフィルター チェーンで順番を取得するときに、別の JPA ルックアップを実行するためだけにデータを破棄する必要があります。
見よ:
public class CustomRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
UsernamePasswordToken userPassToken = (UsernamePasswordToken) token;
String username = userPassToken.getUsername()
User user; // Contains username, password, and roles
// Perform JPA lookup by username...
return constructSimpleAuthenticationInfoFromUser(user);
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// Look up user again? :(
...
}
}
私はいくつかの可能性を検討しました:
- レルム キャッシングを使用します。アプリケーションは分散環境で実行されるため、任意の数の JVM を実行できます。デフォルトのレルム キャッシュ マネージャーの実装では、固有の問題がすべて解決されるわけではなく、エンタープライズ実装のセットアップは、このプロジェクトの範囲外のようです。
- サブジェクトのセッションを使用します。サーバー側の状態はありません。できればそのままにしておきたいです。おそらく、セッションをリクエストスコープのように動作させることができますが、その方法がわからないため、難読化されるリスクがあります。
- 独自の Subject を実装します。通常、リクエストごとに 1 つの Subject インスタンスがあるように見えますが、これをブートストラップする方法が不明であり、多くの潜在的な機能を失うリスクがあります。
- Shiro ThreadContext オブジェクトを使用します。データをスレッドローカル プロパティとして ThreadContext にアタッチできます。サーブレット コンテナは通常、リクエストごとのスレッド モデルに従います。Subject インスタンス自体は、避けられないガベージ コレクションを待って、ここでくつろいでいるように見えます。またシロは文脈を自動的に構築したり解体したりするように見える。ただし、これに関するドキュメントはあまりなく、ソース コードを理解するのは困難です。
最後に、デフォルトの WebSecurityManager は、CustomRealm のシングルトン インスタンスを、JVM ごとに 1 つずつ保持します。ローカル インスタンス プロパティを設定するだけでは、スレッドセーフではありません。
これは、一般的なデータ取得オプションであり、典型的な展開シナリオのようです。それで、私は何が欠けていますか?
ありがとう!