7 Replies Latest reply on Apr 7, 2014 12:30 PM by fuzao

    EJB lookup from servlet not allowed with custom security domain

    fuzao

      Hi, I have an app that launches a thread from a servlet  (in app.war), that looks up from an EJB in separate module (mod1.ejb).

       

      The structure of the project is something like this:

      app.ear (explored)

      |__ app.war (exploded)

      |__ mod1.ejb (exploded)

      |__ mod2.ejb (exploded)

       

      Here is the ejb-jar.xml (old-fashioned EJB 2.x since this is a migration from Jboss 6 to WildFly 8):

      <?xml version="1.0" encoding="UTF-8" standalone="no"?>

       

       

      <ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee;http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd" version="3.2">

        <enterprise-beans>

        <session><display-name>com.quatrosi.be.al.AlertService</display-name><ejb-name>com.quatrosi.be.al.AlertService</ejb-name><home>com.quatrosi.be.al.AlertServiceHome</home><remote>com.quatrosi.be.al.AlertService</remote><ejb-class>com.quatrosi.be.al.AlertServiceEJB</ejb-class><session-type>Stateless</session-type><transaction-type>Bean</transaction-type></session> 

        </enterprise-beans>

       

       

        <assembly-descriptor>

        <security-role><description>USRX</description><role-name>USRX</role-name></security-role>

        <method-permission><role-name>USRX</role-name><method><ejb-name>com.quatrosi.be.al.AlertService</ejb-name><method-name>*</method-name></method></method-permission>

        </assembly-descriptor>

      </ejb-jar>

      My EJB modules have the following configuration in jboss-ejb3.xml:

      <?xml version="1.0"?>

      <jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee"

      xmlns="http://java.sun.com/xml/ns/javaee" xmlns:s="urn:security"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd

      http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd" version="3.1" impl-version="2.0">

       

      <assembly-descriptor>

        <s:security>

         <ejb-name>*</ejb-name>

         <s:security-domain>mysecuritydomain</s:security-domain>

        </s:security>

      </assembly-descriptor>

      </jboss:ejb-jar>

      My security domain is configured as follow:

      <security-domain name="mysecuritydomain" cache-type="default">

        <authentication>

          <login-module code="Remoting" flag="optional">

            <module-option name="password-stacking" value="useFirstPass"/>

          </login-module>

          <login-module code="UsersRoles" flag="required">

            <module-option name="usersProperties" value="${jboss.server.config.dir}/myapp-users.properties"/>

            <module-option name="rolesProperties" value="${jboss.server.config.dir}/myapp-roles.properties"/>

          </login-module>

        </authentication>

      </security-domain>

      My Java code for lookup EJB is:

      Hashtable properties = new Hashtable();
      //properties.put(Context.INITIAL_CONTEXT_FACTORY, factory);
      //properties.put(Context.PROVIDER_URL, provider);
      properties.put(Context.SECURITY_PRINCIPAL, username);
      properties.put(Context.SECURITY_CREDENTIALS, password);
      Context context = new InitialContext(properties);
      
      AppServiceHome home = context.lookup(beanName);
      AppService service = home.create();
      

      WildFly 8 exposes these JNDI names for service:

      java:global/app/mod1/com.quatrosi.be.al.AppService!com.quatrosi.be.al.AppService
      java:app/mod1/com.quatrosi.be.al.AppService!com.quatrosi.be.al.AppService
      java:module/com.quatrosi.be.al.AppService!com.quatrosi.be.al.AppService
      java:jboss/exported/app/mod1/com.quatrosi.be.al.AppService!com.quatrosi.be.al.AppService
      java:global/app/mod1/com.quatrosi.be.al.AppService!com.quatrosi.be.al.AppServiceHome
      java:app/mod1/com.quatrosi.be.al.AppService!com.quatrosi.be.al.AppServiceHome
      java:module/com.quatrosi.be.al.AppService!com.quatrosi.be.al.AppServiceHome
      java:jboss/exported/app/mod1/com.quatrosi.be.al.AppService!com.quatrosi.be.al.AppServiceHome
      

      I can only invoke using java:global and java:jboss/exported namespaces.

       

      I'm getting what seems to be an authentication error:

      javax.ejb.EJBAccessException: JBAS014502: Invocation on method: public abstract com.quatrosi.be.AppService com.quatrosi.be.AppServiceHome.create() throws java.rmi.RemoteException,javax.ejb.CreateException of bean: com.quatrosi.be.al.AppService is not allowed

       

      Can anyone help me with this situation please?

        • 1. Re: EJB lookup from servlet not allowed with custom security domain
          emmartins

          Use the EE Concurrency Utilities introduced with Java EE 7, the threads created/used by these will propagate the invocation context, i.e. the task will run on the different thread as if it was running in the original thread, with the servlet invocation context.

           

          --E

          • 2. Re: EJB lookup from servlet not allowed with custom security domain
            fuzao

            That doesn't work neither.

             

            If I change my method permission to unchecked that works:

            <method-permission><unchecked/><method><ejb-name>com.quatrosi.be.al.AlertService</ejb-name><method-name>*</method-name></method></method-permission>


            I don't know what is wrong with my configuration since I'm able to login with the credentials in myapp-users.properties

            • 3. Re: EJB lookup from servlet not allowed with custom security domain
              emmartins

              Please share details about EE Concurrency Utilities not working, may be a bug...

              • 4. Re: EJB lookup from servlet not allowed with custom security domain
                fuzao

                Dear Eduardo,

                actually I haven't tested with your sugestion since I need to learn that API. I'm used to work with SE and I've been doing just little work with EJB.

                 

                What I've done was try to lookup EJB in "main" thread of the servlet.

                Now I can lookup using java:app namespace, java:app/mod1/com.quatrosi.be.al.AppService!com.quatrosi.be.al.AppServiceHome but failed when invoking create() method with same error.

                 

                Other reference that could be interesting is that I can lookup EJB without any credential no JNDI contenxt. So I'm wondering if the problem is related to authentication.

                • 5. Re: EJB lookup from servlet not allowed with custom security domain
                  emmartins

                  If you can't lookup the EJB in the servlet then you should have an issue wrt to security, but note that once you solve that and try to lookup in another thread it won't work, since the servlet's invocation context won't be propagated to the the "other" thread, and that's where the EE Concurrency Utilities come to rescue.

                   

                  Wrt your security issue, I recommend you to look at quickstart/ejb-security at master · wildfly/quickstart · GitHub and consider updating your app. And perhaps start with the existent security domain and when everything is working replace it with your own.

                  • 6. Re: EJB lookup from servlet not allowed with custom security domain
                    fuzao

                    I understand your mention to use EE Concurrency Utilities perfectly. And I can lookup EJB, even in the same thread of the servlet, I only cannot invoke any method in it.

                    And I can login into app and work without any constraints with EJBs.

                    • 7. Re: EJB lookup from servlet not allowed with custom security domain
                      fuzao

                      Ok let's divide (problems) to conquer

                       

                      I began to debug into picketbox and I realize that the principal is allways anonymous.

                      I've seen in some threads to authenticate before lookup EJB using LoginContext (user admin has USRX role)

                       

                      LoginContext context = new LoginContext("NxGen", new Subject(), new UsernamePasswordCallbackHandler(username, password));

                      context.login();

                       

                      And here goes the stacktrace with wildfly 8 with DEBUG level:

                       

                      11:16:57,211 DEBUG [org.jboss.security] (MSC service thread 1-6) PBOX000292: Insufficient method permissions [principal: null, EJB name: com.quatrosi.be.al.AppService, method: create, interface: Home, required roles: Roles(USERX,), principal roles: Roles(), run-as roles: null]

                      11:17:07,725 DEBUG [org.jboss.security] (MSC service thread 1-6) PBOX000299: Required module org.jboss.security.authorization.modules.DelegatingAuthorizationModule failed

                      11:17:07,726 DEBUG [org.jboss.security] (MSC service thread 1-6) PBOX000325: Authorization processing error: org.jboss.security.authorization.AuthorizationException: PBOX000017: Acces denied: authorization failed

                        at org.jboss.security.plugins.authorization.JBossAuthorizationContext.invokeAuthorize(JBossAuthorizationContext.java:268) [picketbox-4.0.20.Final.jar:4.0.20.Final]

                        at org.jboss.security.plugins.authorization.JBossAuthorizationContext.access$000(JBossAuthorizationContext.java:71) [picketbox-4.0.20.Final.jar:4.0.20.Final]

                        at org.jboss.security.plugins.authorization.JBossAuthorizationContext$1.run(JBossAuthorizationContext.java:147) [picketbox-4.0.20.Final.jar:4.0.20.Final]

                        at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.7.0_17]

                        at org.jboss.security.plugins.authorization.JBossAuthorizationContext.authorize(JBossAuthorizationContext.java:143) [picketbox-4.0.20.Final.jar:4.0.20.Final]

                        at org.jboss.security.plugins.JBossAuthorizationManager.internalAuthorization(JBossAuthorizationManager.java:429) [picketbox-4.0.20.Final.jar:4.0.20.Final]

                        at org.jboss.security.plugins.JBossAuthorizationManager.authorize(JBossAuthorizationManager.java:115) [picketbox-4.0.20.Final.jar:4.0.20.Final]

                        at org.jboss.security.plugins.javaee.EJBAuthorizationHelper.authorize(EJBAuthorizationHelper.java:318) [picketbox-4.0.20.Final.jar:4.0.20.Final]

                        at org.jboss.as.security.service.SimpleSecurityManager.authorize(SimpleSecurityManager.java:271) [wildfly-security-8.0.0.Final.jar:8.0.0.Final]

                        at org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:113) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:95) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.as.ejb3.component.interceptors.EjbExceptionTransformingInterceptorFactories$1.processInvocation(EjbExceptionTransformingInterceptorFactories.java:65) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:55) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64)

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:326)

                        at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:448)

                        at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61)

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:326)

                        at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80)

                        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)

                        at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)

                        at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:185)

                        at org.jboss.as.ejb3.remote.LocalEjbReceiver.processInvocation(LocalEjbReceiver.java:243) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBObjectInterceptor.handleInvocation(EJBObjectInterceptor.java:58) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBHomeInterceptor.handleInvocation(EJBHomeInterceptor.java:83) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.TransactionInterceptor.handleInvocation(TransactionInterceptor.java:42) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:125) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:253) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:198) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:181) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:144) [jboss-ejb-client-2.0.0.Final.jar:2.0.0.Final]

                        at com.sun.proxy.$Proxy23.create(Unknown Source)

                        at com.quatrosi.servlet.services.NxGenServicesServlet.startService(NxGenServicesServlet.java:151)

                        at com.quatrosi.servlet.services.NxGenServicesServlet.startService(NxGenServicesServlet.java:109)

                        at com.quatrosi.servlet.services.NxGenServicesServlet.startServices(NxGenServicesServlet.java:86)

                        at com.quatrosi.servlet.services.NxGenServicesServlet.init(NxGenServicesServlet.java:45)

                        at io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start(ManagedServlet.java:208)

                        at io.undertow.servlet.core.ManagedServlet.createServlet(ManagedServlet.java:116)

                        at io.undertow.servlet.core.DeploymentManagerImpl.start(DeploymentManagerImpl.java:496)

                        at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:87)

                        at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.start(UndertowDeploymentService.java:71)

                        at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)

                        at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)

                        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_17]

                        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_17]

                        at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_17]

                       

                       

                       

                      What am I supposed to do or what I'm doing wrong to authenticate an user in wildfly pior to lookup any secured EJB?