問題
アプリケーション クライアントのクラスに @EJB プロキシを挿入し、Main
その EJB にユーザーが特定のロールにいることを要求するメソッドがある場合、アプリケーション クライアント コンテナー (ACC) は、ユーザーがログインするとすぐにログインすることを要求します。アプリケーション クライアントが起動します。ACC は、クライアントが呼び出すことを念頭に置いていたメソッドを区別しないため、クライアントが実際に必要な役割 (存在する場合) は何であるかを区別しません。 EJB の 1 つのメソッドだけが、特定のロールを必要とするメソッドを持っています。EJB に で明示的に注釈を付けるかどうかは問題ではありません@PermitAll
。ACC は引き続きユーザー名とパスワードの入力を求めます。指定されていない場合、GlassFish 3.1.2.2 (ビルド 5) の実装はすべてを中止し、"ユーザーが認証をキャンセルしました".
テスト環境を整えましょう!
次のようにリモート インターフェイスを宣言します。
@Remote
public interface IRemoteEJB
{
String echoGuest(String returnMe);
String echoAdmin(String returnMe);
}
EJB を記述します (私の問題はシングルトンに関連しているため、ここではあえて別のセッション アノテーションを使用しません!):
@Singleton
/*
* See the following annotation. We explicitly "permit all" on class level.
* Should not cause any ambiguity at all!
*/
@PermitAll
public class myEJB implements IRemoteEJB
{
@Override
public String echoGuest(String returnMe) {
return returnMe; }
@Override
// ..but here we grant access only to administrators:
@RolesAllowed("admin")
public String echoAdmin(String returnMe) {
return returnMe; }
}
クライアント部分に関しては、私が考えることができる最小の実装は次のとおりです。
public class Main
{
@EJB private static remoteProxy;
public static void main(String... args)
{
String reply = remoteProxy.echoGuest("Hello world!");
JOptionPane.showMessageDialog(null, reply);
}
}
結果
クライアントがメソッドに対して "匿名" 呼び出しを正常に行ったと思いますechoGuest
か? いいえ。私は、ACC@EJB
が注入される前であっても、クライアントにユーザー名とパスワードの提供を強制することを発見しました。簡単に言えば、アプリケーション クライアントから EJB へのアクセス認証を混在させることはできません。上記の解決策は、メソッド@RolesAllowed("admin")
から注釈を削除することです。echoAdmin
ある意味では、それは完全に理にかなっています。Main
ACC は、クライアントの起動中にのみアクティブになります。これが、注入されたすべてのリソースをクラス内のアプリケーション クライアントに配置し、それらstatic
も作成する必要があるまさにその理由です。ACC は、EJB のどのメソッドが呼び出されるかどうかを正確に知ることはできません。
@PermitAll
わかりましたが、それはおよび@RolesAllowed
アノテーションの仕様と期待される動作を壊していませんか? アプリケーションクライアントに、特定のロールを必要とする、廃止され、呼び出されたことのないメソッドが 1 つしかない EJB への匿名アクセス権を提供する方法は、地球上にないのでしょうか? 今のところ、これらのメソッドを分離する必要があるのは、私が可能であり、実行すべきであると考えていたアノテーションを使用するだけでなく、EJB を完全に分離するためにロジックをリファクタリングする必要もあります。難しい感じ:'(