14 Replies Latest reply on Jun 20, 2002 4:33 AM by drcharris

    MDB authentication: run-as appears to be ignored

    chewitty

      Hi,

      I am having some difficulty with JAAS authentication and my MDBs. I have setup all the JAAS authentication configuration as per the documentation. I am using ClientLoginModule (client-side) and DatabaseServerLoginModule (server-side). I am using Jboss2.4.4-Tomcat4.0.1 bundle.

      The only way I could get JBoss to pickup the ClientLoginModule instead of the default UsersRolesLoginModule was to use a security_policy.xml file:

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

      <application-policy name = "client-login">

      <login-module code="org.jboss.security.ClientLoginModule" flag="required">
      </login-module>

      </application-policy>
      <application-policy name = "mysecurity_auth">

      <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
      <module-option name="principalsQuery"><![CDATA[SELECT PASSWORD FROM users WHERE PRIM_EMAIL=?]]></module-option>
      <module-option name="rolesQuery"><![CDATA[SELECT NAME, RGROUP FROM roles WHERE USERID=?]]></module-option>
      <module-option name="dsJndiName">java:/jdbc/myDBPool</module-option>
      <module-option name="unauthenticatedIdentity">nobody</module-option>
      </login-module>

      </application-policy>


      I am using FORM-based authentication and everything is working just fine but for my MDBs.

      Problems:
      [1] First I couldn't even post messages to a topic successfully because the SecurityInterceptor kept throwing a security exception on attempting the corresponding MDB onMessage() method. I would have thought that MDB don't expect to enforce security at this point given that the client has no direct interaction with it. The only way I could resolve this problem was to turn-off the SecurityInterceptor for MDBs in standardjboss.xml. I have to admit that I have not fully understood what the implications of doing this would be - has someone else found out something further???

      [2] The other MDB problem is that when calling a method on one f my secured session/entity EJB - it is of course expected to appropriately authenticated. In my deployment descriptor the MDB attributes are appropriately set using the <run-as> element tags in <security-identity>. However, it appears that the container is failing to (a) pick this up or (b) failing to enforce this. Consequently, it is impossible to call a method on a secured EJB. Has anyone been able to fully resolve this issue such that they can enlighten me as well? I have checked and doubled checked he mailing lists and forums and even checked the test example (RunAsMDB) sited on one occasion by Scott but I am still unable to resolve this issue. Please Scott, can you help here??

      This is a typical MDB ejb-jar entry:

      <message-driven id="AdminOrdersMDB">
      <![CDATA[Monitors messages on the AdminOrdersTopic and updates the admin_orders table accordingly]]>

      <ejb-name>AdminOrdersMDB</ejb-name>

      <ejb-class>com.sampel.ejb.AdminOrdersMDBean</ejb-class>

      <transaction-type>Container</transaction-type>
      <acknowledge-mode>Auto-acknowledge</acknowledge-mode>
      <message-driven-destination>
      <destination-type>javax.jms.Topic</destination-type>
      <subscription-durability>Durable</subscription-durability>
      </message-driven-destination>

      <ejb-ref>
      <ejb-ref-name>ejb/OrderManager</ejb-ref-name>
      <ejb-ref-type>Session</ejb-ref-type>
      com.sampel.ejb.OrderManagerHome
      com.sampel.ejb.OrderManager
      <ejb-link>OrderManagerBean</ejb-link>
      </ejb-ref>
      <security-identity>
      <run-as>
      <role-name>nobody</role-name>
      </run-as>
      </security-identity>

      <resource-ref>
      <res-ref-name>mail/Mail</res-ref-name>
      <res-type>javax.mail.Session</res-type>
      <res-auth>Container</res-auth>
      </resource-ref>

      </message-driven>


      All the appropriate roles, including 'nobody' above have been properly setup and tested to be working elsewhere - apart from MDBs. It is also important to add that with security everything works just fine. I also have picked up the fact that I may choose to separate the MDBs into a separate jar - which may be unsecured (as per jboss.xml) - however, why shouldn't I be able to package MDBs in a secured jar normally??

      Any feedback that can help to move this further would be most appreciated.

      Best regards,
      Ferdinand

        • 1. Re: MDB authentication: run-as appears to be ignored
          chewitty

          Hi - [correction]

          My penultimate paragraph should read:

          All the appropriate roles, including 'nobody' above have been properly setup and tested to be working elsewhere - apart from MDBs. It is also important to add that without security everything works just fine. I also have picked up the fact that I may choose to separate the MDBs into a separate jar - which may be unsecured (as per jboss.xml) - however, why shouldn't I be able to package MDBs in a secured jar normally??

          Ferdinand

          • 2. Re: MDB authentication: run-as appears to be ignored
            billyboyo

            I have a similar problem with security. As you, I can get JBoss to call my MDB if I change the security domain of the Message Driven Beans in "standardJBoss.xml". However, this puts the security context under a null principal. When the MDB calls into a secured EJB, I then naturally get a security exception. If I explicitly try to change the security context in the MDB (by logging out and then logging in as a known user), it works with the first call to the MDB, but the second will give a container exception in the JaasSecurityManager.validateCache method.

            Like you, I have set the "run-as" attribute on my MDB, but that is being ignored. What I'd like is to be able to specify the security context of the onMessage() call from JBoss (or at least get the run-as attribute working).

            There seems to be little information (I have the official JBoss docs) on how security is applied during MDB calls. Maybe one of the developers can enlighten us.

            • 3. Re: MDB authentication: run-as appears to be ignored

              Hi, I have to admit that I wrote the MDB container back in the age of dawn, but that I never have done any security configurations on it.

              I do know this:

              1. An MDB will allways be invoked with a principal and credentials set to null.

              2. If it is running i a container where a security manager is installed this null principal and null cred will be checked against the installed LoginModule for the security domain.

              3. If the LoginModule is configured to return a default role and for a null user with a null password this will succed otherwise the invokation will be abondoned.

              4. The run-as role will only ever be used if there was a security manager installed and if the auth process was lucky. If that was the case, I can see nothing in the SecurityInterceptor that would make the run-as not work.

              Bottom line: if you setup a LoginModule to autenticate a null user with a null password an place it in any - as far as I can read the code - role, the run-as role will be honored.

              You could also be adventurous and patch JMSContainerInvoker to run as a principal you specify: for example get the user and password from the mdb config (your JMS provider must let this user in):

              MessageDrivenMetaData config =
              ((MessageDrivenMetaData)container.getBeanMetaData());
              String user = config.getUser();
              String password = config.getPasswd();

              And construct a principal in the invokation:

              try {
              invoker.invoke(id, // Object id - where used?
              ON_MESSAGE, // Method to invoke
              new Object[] {message}, // argument
              tm.getTransaction(), // Transaction
              new SimplePrincipal(user), // Principal
              password); // Cred
              }
              catch (Exception e) {
              log.error("Exception in JMSCI message listener", e);
              }

              //Peter

              • 4. Re: MDB authentication: run-as appears to be ignored
                chewitty

                Hi Peter,

                I take your points, and I am going to investigate further. However, It strikes me a bit odd that <run-as> identity should be ignored - i.e. going against the specification???. What is curious is that in a test example sited in the mailing lists by Scott "RunAsMDB.java) it is implied that <run-as> identity works as expected in the specification. I will have a look at the JMSContainerInvoker again.

                The only way I have been able properly authenticate an MDB calling a secured EJB is by creating a LoginContext programmatically in the onMessage() of the MDB and loging in appropriately.

                Even though it works to do it programmatically, I still believe that it should be possible to use the declarative <run-as> identity to avoid programming in the JAAS authentication.

                I have looked at the JMSContainerInvoker and, you are right, it invokes onMessage() with null principle no matter what - strange!!! So it is quite clearly ignoring the declared <run-as> ... is this a bug Scott ???

                Your patch below appears to be what will resolve this. I have to look more into this and will feedback later.

                Thanks for your reply,
                Ferdinand

                • 5. Re: MDB authentication: run-as appears to be ignored

                  As I see it it is the SecurityInterceptor that should honour run-as, if that interceptor is dissabled or is not working properly with the setup run-as will NOT work.

                  //Peter

                  • 6. Re: MDB authentication: run-as appears to be ignored
                    chewitty

                    Hi Peter,

                    I believe I may have gotten to the bottom of it. Now, believe me the MDBs do actually use the <run-as> eventhough the JMSContainerInvoker listener invokes the onMessage() with null principal etc, as we saw earlier.

                    However, you are right in that the key is the SecurityInterceptor - it enforces, if you like, the <run-as> role identity - if one is specified. But that does not appear to be the whole story.

                    You also have to make sure that the security-domain includes within it the ClientLoginModule - which works with the SecurityAssociation in order to propagate the authentication info. That is, you may have to use both the ClientLoginModule and the DatabaseServerLoginModule (as in my case) for the security-domain.

                    That is not all, of course. There is more! You must of course make sure that all this hardwork is also reflected in the ejb-jar.xml - by adding the corresponding <method-permissions> to the MDBs and of course the <security-identity><run-as>...</run-as></security-identity> and <security-role> entries as well.

                    One more thing. You must also make sure the <module-option name="unauthenticatedIdentity">nobody</module-option> is valid for the DatabaseServerLoginModule. That is, nobody must be a valid principle or username, if you like, for the role-name in the <run-as> entry in ejb-jar.xml.

                    After that, if you still can get it to work then I have to go back to the drawing board.

                    Maybe someone else can try this out and either confirm or correct or add to my experience here. It works for me.

                    Ferdinand

                    • 7. Re: MDB authentication: run-as appears to be ignored

                      Correct.

                      //Peter

                      • 8. Re: MDB authentication: run-as appears to be ignored
                        makeshipgo

                        Chewitty - can you please post your security domain config file?

                        Secondly, do the mdbs have to be in a separate jar in order to run under the clientloginmodule domain?

                        From what i gather from your last posting, it looks like the clientloginmodule for the mdbs will specify the unauthenticatedIndentity which has to be a valid role in your DatabaseServerLogin module... is this assumption correct?

                        thanks.

                        • 9. Re: MDB authentication: run-as appears to be ignored
                          chewitty

                          Hi,

                          A typical security_policy.xml may look like:


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

                          <application-policy name = "client-login">

                          <login-module code="org.jboss.security.ClientLoginModule" flag="required">
                          </login-module>

                          </application-policy>
                          <application-policy name = "my_auth">

                          <login-module code="org.jboss.security.ClientLoginModule" flag="required">
                          </login-module>
                          <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
                          <module-option name="principalsQuery"><![CDATA[SELECT PASSWORD FROM users WHERE USERNAME=?]]></module-option>
                          <module-option name="rolesQuery"><![CDATA[SELECT NAME, RGROUP FROM roles WHERE USERID=?]]></module-option>
                          <module-option name="dsJndiName">java:/jdbc/somePoolName</module-option>
                          <module-option name="unauthenticatedIdentity">nobody</module-option>
                          </login-module>

                          </application-policy>



                          But I believe it should equally work if one were to adapt the either a custom login module or the JBoss DatabaseServerLoginModule to do the same SecurityAssociation initialization that the JBoss ClientLoginModule does. In this case, one could simply use the following entry for both client and server side:


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

                          <application-policy name = "my_auth">

                          <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
                          <module-option name="principalsQuery"><![CDATA[SELECT PASSWORD FROM users WHERE USERNAME=?]]></module-option>
                          <module-option name="rolesQuery"><![CDATA[SELECT NAME, RGROUP FROM roles WHERE USERID=?]]></module-option>
                          <module-option name="dsJndiName">java:/jdbc/somePoolName</module-option>
                          <module-option name="unauthenticatedIdentity">nobody</module-option>
                          </login-module>

                          </application-policy>



                          The second approach is probably more consistent with common usage anywhere else, I would imagine.

                          Yes, the unauthenticatedIndentity you specify must correspond to a valid principal with valid entries on your roles table etc.

                          Hope that helps.
                          Ferdinand

                          • 10. Re: MDB authentication: run-as appears to be ignored
                            drcharris

                            The problem with this approach, at least in 2.4.4 which is what I'm using, is that adding an unauthenticatedIdentity to the LoginModule (in the server auth.conf) allows unauthenticated access from remote clients. This is unacceptable in our application.

                            Has anyone got a solution for 2.4.x that allows MDBs to use run-as properly whilst still forbidding unauthenticated access from remote clients?

                            • 11. Re: MDB authentication: run-as appears to be ignored
                              twhphan

                              I'm using JBoss 3.0 RC 3, whenever I enable the security manager for the EJB container. My MDB won't work. Is there any work around? E.g. May we disable the security manager for all MDBs only, since security for entity/session EJBs are important

                              Will there be a modification before 3.0 final will be released? Or when will this be fixed?

                              Thanks

                              • 12. Re: MDB authentication: run-as appears to be ignored
                                pedrow

                                Same problem is in Jboss3.0 I can't get it to work with UsersRolesLoginModule, okay I can but only when I add unauthenticatedIdentity="nobody" in security domain configuration. This is not acceptable in my case either.

                                I tried to login programaticaly using LoginContext but it seems it doesn't change anything???? Prinicple is still null which I don't understand, any idea what that can be????

                                p.

                                • 13. Re: MDB authentication: run-as appears to be ignored
                                  pedrow

                                  Same problem is in Jboss3.0 I can't get it to work with UsersRolesLoginModule, okay I can but only when I add unauthenticatedIdentity="nobody" in security domain configuration. This is not acceptable in my case either.

                                  I tried to login programaticaly using LoginContext but it seems it doesn't change anything???? Prinicple is still null which I don't understand, any idea what that can be????

                                  p.

                                  • 14. Re: MDB authentication: run-as appears to be ignored
                                    drcharris

                                    For my problem I wrote an interceptor that hard-codes a known principal/credential into the method invocation, and made my MDB container configuration use that. It runs right after the invoker so by the time the security interceptor gets to it everything looks normal. This means your MDBs run with a known identity but still forbids any unauthenticated access to EJBs.

                                    It's a half-solution, but has proven effective here. We're still using 2.4 (specifically 2.4.5) so don't have any JAAS on our JMS.