跨多个EJB跨越用户信息

Gon*_*gui 5 java java-ee-6 ejb-3.1

使用javax.security.Principal,您可以通过注入EJBContextwith 来随时检索用户信息@Resource.

我想要做的是添加额外的信息,这些信息将特定于我的应用程序和我的用户作为一部分Principal.我也试图包括在这一信息contextData()EJBContext,但这只持续了EJB的生命周期,而不是在多个EJB调用.

有没有办法扩展Principal添加任何额外的信息?我宁愿不使用ThreadLocal或修改我的所有EJB签名来传递此信息.

Gon*_*gui 1

终于解决了这个问题。Principal可以在 JBoss AS 中创建自定义。创建一个实现java.security.Principal并添加自定义属性和 getter/setter 的类就足够了。

然后,在配置登录模块(例如DatabaseServerLoginModule)时,在login-config.xml文件中的模块选项中添加一个principalClass选项:

<application-policy name="my-security-domain">
     <authentication>
     <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
          <module-option name="principalClass">com.custom.security.MyCustomPrincipal</module-option>
...
Run Code Online (Sandbox Code Playgroud)

现在的问题是,由于 JBoss 中存在的错误,对注入的调用EJBContext.getCallerPrincipal()不会返回自定义的主体,而是返回 SimplePrincipal 的普通实例!但好消息是,这个问题可以通过以下 JAAS 代码来解决,该代码允许检查 EJB 容器身份验证信息:

try {
      Subject subject = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
      Set<Group> subjectGroups = subject.getPrincipals(Group.class);
      Iterator<Group> iter = subjectGroups.iterator();
      while (iter.hasNext()) {
        Group group = iter.next();
        String name = group.getName();
        if (name.equals("CallerPrincipal")) {
          Enumeration<? extends Principal> members = group.members();
          if (members.hasMoreElements()) {
            context = members.nextElement();
            myCustomPrincipal = (MyCustomPrincipal) context;
          }
        }
      }
    } catch (PolicyContextException e) {
        ....
    }
Run Code Online (Sandbox Code Playgroud)

我将上面的代码包装在一个 POJO 中,我可以将其注入到我的 EJB 中以获取主体,就像 EJBContext 类所做的那样。