3 Replies Latest reply on Sep 26, 2011 2:59 PM by stevemaring

    LdapLoginModule for web app auth

    stevemaring

      I'm having trouble getting my web-app to authenticate properly with my security-domain in JBoss AS 6.1.0.Final.

       

      My web.xml is configured for:

       

      {code:xml}

      <security-constraint>

                <web-resource-collection>

                          <web-resource-name>Everything</web-resource-name>

                          <url-pattern>/*</url-pattern>

                          <http-method>GET</http-method>

                          <http-method>POST</http-method>

                </web-resource-collection>

                <auth-constraint>

                          <!-- need to be an ActiveDirectory "memberOf" one of these ... -->

                          <role-name>Development</role-name>

                          <role-name>Helpdesk</role-name>

                </auth-constraint>

      </security-constraint>

       

      <login-config>

                <auth-method>BASIC</auth-method>

                <realm-name>My Realm</realm-name>

      </login-config>

       

      <security-role>

                <role-name>Development</role-name>

      </security-role>

      <security-role>

                <role-name>Helpdesk</role-name>

      </security-role>

      {code}

       

      and my jboss-web.xml has:

       

      {code:xml}

      <jboss-web>

         <context-root>/myApp</context-root>

         <security-domain>java:/jaas/XADSRealm</security-domain>

      </jboss-web>

      {code}

       

       

      JNDIView in the jmx-console has confirm existence of that name under the "java: Namespace":

       

      +- jaas (class: javax.naming.Context)

      |   +- XADSRealm (class: org.jboss.security.plugins.SecurityDomainContext)

       

       

      The security domain is configured in my login-config.xml like this:

       

      {code:xml}

      <application-policy name="XADSRealm" extends="other">

                <authentication>

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

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

                          </login-module>

                          <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required" >

                                    <module-option name="java.naming.provider.url">ldap://10.175.3.200:389/</module-option>

                                    <module-option name="rolesCtxDN">DC=sample,DC=com</module-option>

                                    <module-option name="matchOnUserDN">false</module-option>

                                    <module-option name="principalDNPrefix">sAMAccountName=</module-option>

                                    <module-option name="principalDNSuffix">,DC=sample,DC=com</module-option>

                                    <module-option name="uidAttributeID">sAMAccountName</module-option>

                                    <module-option name="roleAttributeID">memberOf</module-option>

                                    <module-option name="roleAttributeIsDN">true</module-option>

                                    <module-option name="roleNameAttributeID">name</module-option>

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

                          </login-module>

                          <login-module

                                    code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required">

                                    <module-option name="userName">username</module-option>

                                    <module-option name="password">574e4454d95c79174f1f41ab21df8598de921bc</module-option>

                                    <module-option name="managedConnectionFactoryName">jboss.jca:service=XATxCM,name=myXADS</module-option>

                          </login-module>

                </authentication>

      </application-policy>

      {code}

       

      However, whenever I start the web app and try to log in, my server says:

       

      ERROR [org.jboss.security.auth.spi.UsersRolesLoginModule] Failed to load users/passwords/role files: java.io.IOException: No properties file: users.properties or defaults: defaultUsers.properties found

       

      Which is the sort of thing I would expect to see if no authenticating login module was present, and it was trying to use the default.

       

      I've been doing a great deal of RTFMing, but I haven't been able to figure out what I'm missing.  I have TRACE enabled for security, but it is not telling me anything interesting.

       

      In the larger scheme of things, I want the LdapLoginModule to handle the authentication and roles for the web app, and for the principal to be available in ThreadLocal when a DB connection is pulled out of the pool for a requesting EJB.

       

      In my xa-datasource, I have defined a valid-connection-checker-class-name which overrides org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker like this:

       

      {code}

          @Override

          public SQLException isValidConnection(Connection conn) {

       

              super.isValidConnection(conn);

       

              Principal currentPrincipal = null;

              try {

                  currentPrincipal = SecurityAssociation.getPrincipal();

              } catch (SecurityException se) {

                  log.error("policy does not seem to have RuntimePermission(\"org.jboss.security.SecurityAssociation.getPrincipalInfo\")",se);

                  return new SQLException("policy does not seem to have RuntimePermission(\"org.jboss.security.SecurityAssociation.getPrincipalInfo\")",se);

              }

       

              if (currentPrincipal == null) {

                  log.error("Principal info not found in ThreadLocal");

                  return new SQLException("Principal info not found in ThreadLocal");

              }

              String clientId = currentPrincipal.getName();

       

              OracleConnection oracleConnection = (OracleConnection) conn;

       

              String metrics[] = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];

              metrics[OracleConnection.END_TO_END_CLIENTID_INDEX] = clientId;

              try {

                  oracleConnection.setEndToEndMetrics(metrics, (short) 0);

              } catch (SQLException se) {

                  log.error("unable to set clientId " + clientId + " on Oracle connection",se);

                  return new SQLException("unable to set clientId " + clientId + " on Oracle connection",se);

              }

       

              return null;

          }

      {code}

       

      So, I need the principal, as authenticated via the LdapLoginModule, to be available when an EJB asks for a connection from the pool.  The purpose here is for auditing, so that we know exactly who used the GUI to change data in the database.

       

       

      -Steve Maring

      Tampa, FL

        • 1. Re: LdapLoginModule for web app auth
          stevemaring

          I think the extends="other"on the application-policy may have been creating problems.

           

          Now I just need to figure out why I'm getting

           

          DEBUG [org.apache.catalina.authenticator.AuthenticatorBase]  Failed authenticate() test

           

          I did not enter "test" as my user!

          • 2. Re: LdapLoginModule for web app auth
            stevemaring

            I made a bit more progress on this.  I was not getting any debug logs because I misspelled the logging catagory.  Ooops!

             

            I think I am getting close, my login-module config for my ActiveDirectory LdapExtLoginModule now looks like this:

             

             

            <login-module code="org.jboss.security.auth.spi.LdapExtLoginModule" flag="required" >

               <module-option name="debug">true</module-option>
               <module-option name="java.naming.security.authentication">simple</module-option>
               <module-option name="java.naming.provider.url">ldap://10.175.3.200:389/</module-option>

               <module-option name="bindDN">GENTIVA\prod_gps</module-option>
               <module-option name="bindCredential"><![CDATA[password]]></module-option>

               <module-option name="baseCtxDN">DC=gentiva,DC=ghsnet,DC=com</module-option>
               <module-option name="matchOnUserDN">false</module-option>
               <module-option name="baseFilter">(sAMAccountName={0})</module-option>
               <module-option name="uidAttributeID">sAMAccountName</module-option>
               <module-option name="rolesCtxDN">DC=gentiva,DC=ghsnet,DC=com</module-option>
               <module-option name="roleFilter">(member={1})</module-option>
               <module-option name="roleAttributeID">memberOf</module-option>
               <module-option name="roleAttributeIsDN">true</module-option>
               <module-option name="roleNameAttributeID">cn</module-option>
               <module-option name="roleRecursion">-1</module-option>
               <module-option name="searchScope">SUBTREE_SCOPE</module-option>
               <module-option name="allowEmptyPasswords">false</module-option>
            </login-module>

             

             

            What I have noticed is that when I try to login, if I give it a VALID user, I will see in the logs that it finds the user and starts assigning roles, but invariably ends up NOT accepting what I know to be a valid password!

             

             

            14:29:57,523 TRACE [org.jboss.security.auth.spi.LdapExtLoginModule] Security domain: LifeSmartXADSRealm-dgentiva
            14:29:57,523 TRACE [org.jboss.security.auth.spi.LdapExtLoginModule] login
            14:29:57,523 TRACE [org.jboss.security.auth.spi.LdapExtLoginModule] Logging into LDAP server, env={uidAttributeID=sAMAccountName,baseFilter=(sAMAccountName={0}), allowEmptyPasswords=false, java.naming.security.credentials=***, jboss.security.security_domain=LifeSmartXADSRealm-dgentiva, java.naming.security.authentication=simple, matchOnUserDN=false, baseCtxDN=DC=gentiva,DC=ghsnet,DC=com, roleAttributeIsDN=true, rolesCtxDN=DC=gentiva,DC=ghsnet,DC=com, java.naming.security.principal=GENTIVA\prod_gps, debug=true, searchScope=SUBTREE_SCOPE, roleRecursion=-1, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, roleFilter=(member={1}), roleNameAttributeID=cn, java.naming.provider.url=ldap://10.175.3.200:389/, roleAttributeID=memberOf, bindDN=GENTIVA\prod_gps, bindCredential=password}
            14:29:57,664 TRACE [org.jboss.security.auth.spi.LdapExtLoginModule] Logging into LDAP server, env={uidAttributeID=sAMAccountName,baseFilter=(sAMAccountName={0}), allowEmptyPasswords=false, java.naming.security.credentials=***, jboss.security.security_domain=LifeSmartXADSRealm-dgentiva, java.naming.security.authentication=simple, matchOnUserDN=false, baseCtxDN=DC=gentiva,DC=ghsnet,DC=com
            , roleAttributeIsDN=true, rolesCtxDN=DC=gentiva,DC=ghsnet,DC=com, java.naming.security.principal=CN=Maring\, Steven,OU=Users,OU=FLTPN,DC=Gentiva,DC=GHSNet,DC=com, debug=true, searchScope=SUBTREE_SCOPE, roleRecursion=-1, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, roleFilter=(member={1}), roleNameAttributeID=cn, java.naming.provider.url=ldap://10.175.3.200:389/, roleAttributeID=memberOf, bindDN=GENTIVA\prod_gps, bindCredential=password}
            14:29:57,976 TRACE [org.jboss.security.auth.spi.LdapExtLoginModule] Assign user to role NY MELVILLE NETWMGMT
            14:29:58,023 TRACE [org.jboss.security.auth.spi.LdapExtLoginModule] Using roleDN: CN=-LNYMEL-D-NETWMGMT,OU=Groups,OU=NYMEL,DC=Gentiva,DC=GHSNet,DC=com

            ...

            14:30:05,116 TRACE [org.jboss.security.auth.spi.LdapExtLoginModule] Assign user to role .LifeSmartDevelopment
            14:30:05,210 TRACE [org.jboss.security.auth.spi.LdapExtLoginModule] Assign user to role CSTampa-All Associates
            14:30:05,257 DEBUG [org.jboss.security.auth.spi.LdapExtLoginModule] Bad password for username=ssmaring
            14:30:05,257 TRACE [org.jboss.security.auth.spi.LdapExtLoginModule] abort
            14:30:05,257 TRACE [org.jboss.security.plugins.auth.JaasSecurityManagerBase.LifeSmartXADSRealm-dgentiva] Login failure: javax.security.auth.login.FailedLoginException: Password Incorrect/Password Required
                    at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:252) [:3.0.0.CR2]

             

             

            I know the password is valid because I can log into the domain with it, and I can use JXEplorer LDAP browser to connect.  Albiet I just used "ssmaring" as the user in the browser, and "GENTIVA\ssmaring" as the user in JXEplorer.

            • 3. Re: LdapLoginModule for web app auth
              stevemaring

              I just added

               

              <module-option name="java.naming.referral">follow</module-option>

               

              to my LdapExtLoginModule, and it now WORKS!   Role constraints and all!   Woohoo!