从纯客户端调用远程EJB(通过IIOP的RMI)时如何传播JAAS主题


问题内容

我正在使用自定义主体测试JAAS主题从原始Java运行时上运行的独立EJB客户端到JavaEE服务器的传播。我的目标是JBoss和WebSphere实现。

根据这个论坛主题,我期望它将与JBoss轻松配合。

这是我的EJB客户端代码段:

Subject subject = new Subject();
Principal myPrincipal = new MyPrincipal("me I myself");
subject.getPrincipals().add(myPrincipal);

PrivilegedExceptionAction<String> action = new PrivilegedExceptionAction<String>() {
    public String run() throws Exception {
            String result;
            System.out.println("Current Subject: " + Subject.getSubject(AccessController.getContext()));
            InitialContext ic = new InitialContext();
            Business1 b = (Business1) ic.lookup("StatelessBusiness1");
            result = b.getNewMessage("Hello World");
            return result;
        }
    };

result = subject.doAs(subject, action);
System.out.println("result "+result);

服务器端代码是:

public String getNewMessage(String msg) {
    System.out.println("getNewMessage principal: " + sessionContext.getCallerPrincipal());
    System.out.println("Current Subject: " + Subject.getSubject(AccessController.getContext()));
    return "getNewMessage: " + msg;
}

可以肯定的是,即使这是默认行为,我也将这一部分添加到了ejb-jar.xml会话bean中:

<security-identity>
   <use-caller-identity/>
</security-identity>

我的会话bean没有任何角色的保护。

根据此IBM
WebSphere信息中心部分
,我还启用了system属性com.ibm.CSI.rmiOutboundPropagationEnabled=true

从技术上讲,该服务调用可以在JBoss或WebSphere上正常工作。但是,包括在客户端上创建的我的自定义主体在内的JAAS主题不会传播到服务器。或者,当然,在Subject创建JNDI上下文和EJB调用之前转储就可以了。

我为服务器和客户端(IBM Java6 SR9 FP2
…)运行相同的Java运行时版本MyPrincipal,服务器ClassPath中提供了可序列化的类(AppServer/lib/ext对于WebSphere,server/default/lib对于JBoss)

WebSphere转储:

[8/31/12 11:56:26:514 CEST] 00000024 SystemOut     O getNewMessage principal: UNAUTHENTICATED
[8/31/12 11:56:26:515 CEST] 00000024 SystemOut     O Current Subject: null

JBoss转储:

 12:30:20,540 INFO  [STDOUT] getNewMessage principal: anonymous
 12:30:20,540 INFO  [STDOUT] Current Subject: null

当然,我错过了某种魔术。你知道哪一个吗?


问题答案:

我怀疑您没有在WAS服务器上启用安全性。因为未启用安全性,并且您未向WAS进行身份验证,所以没有凭据。因此,您的呼叫将getCallerPrincipal返回未经授权的状态。

如果在WAS中打开应用程序安全性,则必须通过CSIv2协议进行身份验证。在独立客户端中创建自己的JAAS主题将无法完成。如果可以,那么任何人都可以创建“嘿,是我”凭证,然后登录到他们想要的任何远程EJB。

通过将您的主题附加到运行中的执行线程,您的代码将在服务器上工作。主题/凭证流经电线需要协议来实现主题信息的序列化,并确保在凭证中声明身份的一方的信任。从一个独立的客户端,WAS接受基本授权,LTPA和kerberos形式的用户信息。可以在管理控制台内的入站CSIv2配置上进行配置。我早先引用的“信息中心”链接中对此进行了记录。

这很有趣。祝好运。