【发布时间】:2013-05-10 09:38:43
【问题描述】:
问题
当我在应用程序客户端的Main 类中注入一个@EJB 代理,并且该EJB 有一个方法要求用户具有特定角色时,应用程序客户端容器(ACC)将要求用户应用程序客户端启动后立即登录。 ACC 不会区分客户端考虑调用的方法,因此客户端实际上需要哪些角色(如果有的话)。实际上,这意味着我的客户端无法正确连接到服务器,如果只是 EJB 的一个单一方法具有一个需要特定角色的方法。如果我们用@PermitAll 明确地注释EJB 并不重要。 ACC 仍然会提示输入用户名和密码,如果没有给出,那么我的 GlassFish 3.1.2.2 (build 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 的访问身份验证。上面的解决方案是从echoAdmin 方法中删除@RolesAllowed("admin") 注释。
从某种意义上说,这是完全有道理的。 ACC 仅在客户端启动期间处于活动状态,这正是我们需要将所有注入的资源放入应用程序客户端的原因,既要放在 Main 类中,也要把它们设为 static。 ACC 根本无法确切知道 EJB 中的哪些方法将被调用。
好的,但这不会破坏@PermitAll 和@RolesAllowed 注释的规范和预期行为吗?世界上没有任何方法可以为应用程序客户端提供匿名访问 EJB 的权限,该 EJB 只有一个过时的、从未调用过的需要特定角色的方法?到目前为止,我不仅必须将这些方法与我认为可以而且应该做的注释分开,而且我还必须重构逻辑以完全分开 EJB:s。感觉很难:'(
【问题讨论】:
标签: jakarta-ee authentication anonymous application-client acc