2 Replies Latest reply on Sep 11, 2007 9:26 AM by jsonic7

    EJB Client and Digest Auth using same SecurityDomain

    joff

      Ok, I seem to have run into a bit of an issue with my application.

      Firstly, I have an application-policy set up in login-config.xml, and configured with the web-tier, such that in order to access any servlets (actually web services), it requires DIGEST authentication (looked up in the database)

      Here is the login-config.xml. Everything else in it is as per default:

      <application-policy name="MyDomain">
       <authentication>
       <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required">
       <module-option name = "dsJndiName">java:/myDS</module-option>
      
       <module-option name = "principalsQuery">SELECT password_hash FROM auth WHERE user_id=?</module-option>
       <module-option name = "rolesQuery">SELECT role AS Role,"Roles" AS RoleGroup FROM role WHERE user_id=?</module-option>
       <module-option name = "hashAlgorithm">MD5</module-option>
       <module-option name = "hashEncoding">rfc2617</module-option>
       <module-option name = "hashUserPassword">false</module-option>
       <module-option name = "hashStorePassword">true</module-option>
       <module-option name = "passwordIsA1Hash">true</module-option>
       <module-option name = "storeDigestCallback">org.jboss.security.auth.spi.RFC2617Digest</module-option>
       </login-module>
       </authentication>
       </application-policy>


      These services access EJBs, which are set up thus:

      @Stateful
      @Local(CategoriesManagerLocal.class)
      @SecurityDomain("MyDomain")
      @RolesAllowed({"Soap","Native"})
      public class CategoriesManagerBean implements CategoriesManagerLocal {



      This is working fine at the moment, HOWEVER, I also need to access these beans from an incoming JCA Resource Adapter (i.e. a custom TCP/IP protocol) which, as part of the protocol does it's own DIGEST authentication implementation. What I need to do, is programatically authenticate this user with the container, so that I can then access these same beans.

      I had tried accessing them like this:
      Properties env = new Properties();
      env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.LoginInitialContextFactory");
      env.setProperty(Context.PROVIDER_URL, "jnp://localhost:1099");
      env.setProperty(Context.SECURITY_PROTOCOL, "MyDomain");
      env.setProperty(Context.SECURITY_PRINCIPAL, String.valueOf(user.getId()));
      env.setProperty(Context.SECURITY_CREDENTIALS, user.getPasswordHash());
      
      Context ctx = new InitialContext(env);
      CategoriesManagerLocal categoriesBean = (CategoriesManagerLocal) ctx.lookup("myapp/CategoriesManagerBean/local");
      categoriesBean.doMyAction();


      This, naturally fails, as I'm passing in the already hashed password (I cannot access the plaintext of it) from the database, as the credentials, but the settings in the application-policy mean that it will try and use that hashed data as the plaintext, and thus I get:

      FATAL [com.myorg.myapp] Failed to login using protocol=MyDomain


      So I tried to add a second application-policy, "MyDomainInternal" to login-config.xml, which has all the hashing options taken out, and referring to that in the SECURITY_PROTOCOL, which seems to authenticate the user ok, but then it seems to also check against the "MyDomain" policy, and fails. Is this because I have specified @SecurityDomain("MyDomain") on the EJB? There doesn't seem to be any way to define multiple domains on a bean.

      Logfile with security TRACE options enabled follows:
      2007-06-07 16:01:51,701 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] Begin getAppConfigurationEntry(MyDomainInternal), size=10
      2007-06-07 16:01:51,701 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] End getAppConfigurationEntry(MyDomainInternal), authInfo=AppConfigurationEntry[
      ]:
      [0]
      LoginModule Class: org.jboss.security.auth.spi.DatabaseServerLoginModule
      ControlFlag: LoginModuleControlFlag: required
      Options:name=rolesQuery, value=SELECT role AS Role,"Roles" AS RoleGroup FROM role WHERE user_id=?
      name=principalsQuery, value=SELECT password_hash FROM auth WHERE user_id=?
      name=dsJndiName, value=java:/myDS
      
      2007-06-07 16:01:51,702 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] initialize, instance=@2036027929
      2007-06-07 16:01:51,702 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Security domain: FirstAlertGatewayInternal
      2007-06-07 16:01:51,702 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] DatabaseServerLoginModule, dsJndiName=java:/myDS
      2007-06-07 16:01:51,702 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] principalsQuery=SELECT password_hash FROM auth WHERE user_id=?
      2007-06-07 16:01:51,702 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] rolesQuery=SELECT role AS Role,"Roles" AS RoleGroup FROM role WHERE user_id=?
      2007-06-07 16:01:51,702 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] suspendResume=true
      2007-06-07 16:01:51,702 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] login
      2007-06-07 16:01:51,703 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] suspendAnyTransaction
      2007-06-07 16:01:51,704 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Excuting query: SELECT password_hash FROM auth WHERE user_id=?, with username: 0
      2007-06-07 16:01:51,705 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Obtained user password
      2007-06-07 16:01:51,705 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] resumeAnyTransaction
      2007-06-07 16:01:51,706 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] User '0' authenticated, loginOk=true
      2007-06-07 16:01:51,706 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] commit, loginOk=true
      2007-06-07 16:01:51,706 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] getRoleSets using rolesQuery: SELECT role AS Role,"Roles" AS RoleGroup FROM role WH
      ERE user_id=?, username: 0
      2007-06-07 16:01:51,706 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] suspendAnyTransaction
      2007-06-07 16:01:51,709 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Excuting query: SELECT role AS Role,"Roles" AS RoleGroup FROM role WHERE user_id=?,
       with username: 0
      2007-06-07 16:01:51,710 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Assign user to role Native
      2007-06-07 16:01:51,710 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Assign user to role Soap
      2007-06-07 16:01:51,710 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] resumeAnyTransaction
      2007-06-07 16:01:51,789 TRACE [org.jboss.security.SecurityAssociation] getPrincipal, principal=null
      2007-06-07 16:01:51,789 TRACE [org.jboss.security.plugins.JaasSecurityManager.MyDomain] Begin isValid, principal:null, cache info: null
      2007-06-07 16:01:51,789 TRACE [org.jboss.security.plugins.JaasSecurityManager.MyDomain] defaultLogin, principal=null
      2007-06-07 16:01:51,790 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] Begin getAppConfigurationEntry(MyDomain), size=10
      2007-06-07 16:01:51,790 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] End getAppConfigurationEntry(MyDomain), authInfo=AppConfigurationEntry[]:
      [0]
      LoginModule Class: org.jboss.security.auth.spi.DatabaseServerLoginModule
      ControlFlag: LoginModuleControlFlag: sufficient
      Options:name=hashEncoding, value=rfc2617
      name=rolesQuery, value=SELECT role AS Role,"Roles" AS RoleGroup FROM role WHERE user_id=?
      name=principalsQuery, value=SELECT password_hash FROM auth WHERE user_id=?
      name=hashUserPassword, value=false
      name=passwordIsA1Hash, value=true
      name=hashAlgorithm, value=MD5
      name=hashStorePassword, value=true
      name=storeDigestCallback, value=org.jboss.security.auth.spi.RFC2617Digest
      name=dsJndiName, value=java:/myDS
      
      2007-06-07 16:01:51,790 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] initialize, instance=@5298117
      2007-06-07 16:01:51,790 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Security domain: MyDomain
      2007-06-07 16:01:51,790 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Password hashing activated: algorithm = MD5, encoding = rfc2617, charset = {default
      }, callback = null, storeCallback = org.jboss.security.auth.spi.RFC2617Digest
      2007-06-07 16:01:51,791 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] DatabaseServerLoginModule, dsJndiName=java:/myDS
      2007-06-07 16:01:51,791 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] principalsQuery=SELECT password_hash FROM auth WHERE user_id=?
      2007-06-07 16:01:51,791 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] rolesQuery=SELECT role AS Role,"Roles" AS RoleGroup FROM role WHERE user_id=?
      2007-06-07 16:01:51,791 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] suspendResume=true
      2007-06-07 16:01:51,791 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] login
      2007-06-07 16:01:51,791 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Authenticating as unauthenticatedIdentity=null
      2007-06-07 16:01:51,791 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] suspendAnyTransaction
      2007-06-07 16:01:51,792 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Excuting query: SELECT password_hash FROM auth WHERE user_id=?, with username: null
      2007-06-07 16:01:51,793 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] Query returned no matches from db
      2007-06-07 16:01:51,793 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] resumeAnyTransaction
      2007-06-07 16:01:51,794 TRACE [org.jboss.security.auth.spi.DatabaseServerLoginModule] abort
      2007-06-07 16:01:51,794 TRACE [org.jboss.security.plugins.JaasSecurityManager.FirstAlertGateway] Login failure
      javax.security.auth.login.FailedLoginException: No matching username found in Principals
       at org.jboss.security.auth.spi.DatabaseServerLoginModule.getUsersPassword(DatabaseServerLoginModule.java:152)
       at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:206)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      ...


      Am I close, or totally barking up the wrong tree?


        • 1. Re: EJB Client and Digest Auth using same SecurityDomain
          joff

          I've solved the problem myself, here it is in case someone else has a similar issue:

          1) You can have multiple 'login-module' elements per 'authentication' element in login-config.xml, which you can set to 'optional', so that if one fails, the other one will be tried, and the entire authentication won't fail.

          2) In order for my EJB client (running inside the container) to authenticate itself with the container (using the Properties as above) then you also need the ClientLoginModule to be present in the config for the security domain

          New, improved login-config.xml follows:

          <application-policy name="MyDomain">
           <authentication>
          
           <!-- Module for doing DIGEST authentication from the web tier -->
           <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "optional">
           <module-option name = "dsJndiName">java:/myDS</module-option>
           <module-option name = "principalsQuery">SELECT password_hash FROM auth WHERE user_id=?</module-option>
           <module-option name = "rolesQuery">SELECT role AS Role,"Roles" AS RoleGroup FROM role WHERE user_id=?</module-option>
           <module-option name = "hashAlgorithm">MD5</module-option>
           <module-option name = "hashEncoding">rfc2617</module-option>
           <module-option name = "hashUserPassword">false</module-option>
           <module-option name = "hashStorePassword">true</module-option>
           <module-option name = "passwordIsA1Hash">true</module-option>
           <module-option name = "storeDigestCallback">org.jboss.security.auth.spi.RFC2617Digest</module-option>
           </login-module>
          
           <!-- Module for doing authentication from within the application, already have the hashed password -->
           <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "optional">
           <module-option name = "dsJndiName">java:/myDS</module-option>
           <module-option name = "principalsQuery">SELECT password_hash FROM auth WHERE user_id=?</module-option>
           <module-option name = "rolesQuery">SELECT role AS Role,"Roles" AS RoleGroup FROM role WHERE user_id=?</module-option>
           </login-module>
          
           <!-- Client Login module so that the security context can be set for invoking EJBs -->
           <login-module code = "org.jboss.security.ClientLoginModule" flag = "required">
           <module-option name="restore-login-identity">true</module-option>
           </login-module>
          
           </authentication>
           </application-policy>



          • 2. Re: EJB Client and Digest Auth using same SecurityDomain
            jsonic7

            Hey joff!

            Just wanted to say thank you for posting the resolution,
            found it just in time before giving up ;)

            cheers,
            sonic