Wildfly 15 从 jax rs 登录用户获取 Singleton 中的 EJBContext

Wildfly 15 get EJBContext in Singleton from jax rs logged in user

我想从登录用户那里获取单例中的调用方主体。用户正在使用 username/password

对其余服务进行身份验证

安全域在jboss-web.xml中war

<security-domain>application-security</security-domain>

war 中的端点是:

@Path("/message/{message}")
public class MyRessource
{  
   @EJB
   MySingleton singletonBean;

   @GET
   public Response resource(@PathParam("message") String message)
   {        
        singletonBean.printText(message);
        System.out.println("called from: " + ctx.getUserPrincipal().getName());
}

单例在自己的项目中,并在 war 中作为依赖项提供。

@Stateless
public class MySingletonBean implements MySingleton
{

    @Resource
    EJBContext context;

    @Resource
    SessionContext ctx;

  public void printText(String text) {
      System.out.println(text + ":: EJBContext: " + context.getCallerPrincipal().getName() + "  SessionContext: " + ctx.getCallerPrincipal().getName());      
  }

}

我的web.xml:

<web-app>
    <security-role>
        <role-name>Admin</role-name>
    </security-role>

    <security-constraint>
        <web-resource-collection>
            <url-pattern>/*</url-pattern>
            <http-method-omission>OPTIONS</http-method-omission>
        </web-resource-collection>
        <auth-constraint>
            <role-name>Admin</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>BASIC</auth-method>
    </login-config>
</web-app>

独立-完整-ha.xml

<subsystem xmlns="urn:wildfly:elytron:5.0" ...>
   [...]
   <security-domain name="application-security" default-realm="application-properties" permission-mapper="default-permission-mapper">
      <realm name="application-properties"/>
   </security-domain>
   [...]
</subsystem>
   [...]

<http-authentication-factory name="application-security-http" security-domain="application-security" http-server-mechanism-factory="global">
   <mechanism-configuration>
      <mechanism mechanism-name="BASIC"/>
   </mechanism-configuration>
</http-authentication-factory>
[...]

<security-domains>
   <security-domain name="application-security" default-realm="application-properties" permission-mapper="default-permission-mapper">
      <realm name="application-properties"/>
    </security-domain>
   [...]
</security-domains>
[...]

<subsystem xmlns="urn:jboss:domain:security:2.0">
   <security-domains>
      <security-domain name="application-security">
         <authentication>
            <login-module code="UsersRoles" flag="required">
               <module-option name="usersProperties" value="file://${jboss.server.config.dir}/context-users.properties"/>
                <module-option name="rolesProperties" value="file://${jboss.server.config.dir}/context-roles.properties"/>
             </login-module>
          </authentication>
     </security-domain>
     [...]
</subsystem>
[...]

<subsystem xmlns="urn:boss:domain:undertow"...>
    <application-security-domains>
        <application-security-domain name="application-security" http-authentication-factory="application-security-http"/>
    </application-security-domains>
    [...]
</subsystem>

但我作为校长总是匿名的。

我做错了什么?

你这里至少有三个问题:

  1. <subsystem xmlns="urn:jboss:domain:security:2.0"> 是遗留的配置元素,不 link 与 elytron 同步;

  2. 您完全缺少 ejb3 安全配置;

  3. 您的 EJB 方法不受 @RolesAllowed(...) 保护。

我得到了一个类似的例子:

  1. 创建一个 elytron 属性领域:

    /subsystem=elytron/properties-realm=DemoPropsRealm:add(groups-attribute=groups,\
       groups-properties={\
         path=demo-roles.properties,relative-to=jboss.server.config.dir},\
       users-properties={\
         path=demo-users.properties,relative-to=jboss.server.config.dir,plain-text=true})
    
  2. 创建一个 elytron 安全域:

    /subsystem=elytron/security-domain=DemoDomain:add(\
       realms=[{realm=DemoPropsRealm,role-decoder=groups-to-roles}],\
       default-realm=DemoPropsRealm,permission-mapper=default-permission-mapper)
    
  3. 创建映射到我们的 DemoDomain 的 elytron http 身份验证工厂:

    /subsystem=elytron/http-authentication-factory=demo-http-auth:add(\
       http-server-mechanism-factory=global,\
       security-domain=DemoDomain,\
       mechanism-configurations=[{\
         mechanism-name=BASIC,\
         mechanism-realm-configurations=[{\
           realm-name=DemoApplicationDomain\
         }]\
       }])
    
  4. 将一个 ejb3 子系统应用程序安全域映射到我们的 DemoDomain

    /subsystem=ejb3/application-security-domain=\
        DemoApplicationDomain:add(security-domain=DemoDomain)
    
  5. Link 一个 undertow 子系统应用程序安全域到我们的 http-authentication-factory:

    /subsystem=undertow/application-security-domain=\
        DemoApplicationDomain:add(http-authentication-factory=demo-http-auth)
    

    "DemoApplicationDomain" 将是 web.xml 的 login-config 元素和 jboss-web.xml 的 security-domain 中的域名文件.

  6. 在您的 EJB 方法上声明允许的角色:

    @RolesAllowed("Admin")
    public void printText(String text) {
        System.out.println(text + ":: EJBContext: " + context.getCallerPrincipal().getName()
         + "  SessionContext: " + ctx.getCallerPrincipal().getName());      
    }
    

示例源位于 GitHub at jax-rs-basic-auth