5 Replies Latest reply on Jul 13, 2007 5:06 AM by sztank

    Passing current user identity to the back-end database

    sztank

      Hi,

      I'm developing an application with the following requirement:

      All users have a database accounts and the application level authorization should be used also with the database. So I need to pass through the current user identity to the back-end database.

      I'm using Jboss as 4.0.5 and Jboss Seam 1.2.1. The project I start with is generated with seam-gen utility. I get some directions on the Seam forum that this should be possible with proper configuration of the JCA datasource.

      According to the informations I founded on wiki and docs I trying to use CallerIdentityLoginModule in the following way:

      I added policy to the login-config.xml file

      <application-policy name = "testdbRealm">
       <authentication>
       <login-module code = "org.jboss.resource.security.CallerIdentityLoginModule" flag = "required">
       <module-option name = "userName">dumy</module-option>
       <module-option name = "password">dumy_pwd</module-option>
       <module-option name = "managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=dbtestDatasource</module-option>
       </login-module>
       </authentication>
      </application-policy>
      


      datasource config file dbtest-ds.xml:
      <datasources>
       <local-tx-datasource>
       <jndi-name>dbtestDatasource</jndi-name>
       <connection-url>jdbc:postgresql:dbtest</connection-url>
       <driver-class>org.postgresql.Driver</driver-class>
       <security-domain>testdbRealm</security-domain>
       </local-tx-datasource>
      </datasources>
      


      web.xml file:
      <security-constraint>
       <display-name>Restrict raw XHTML Documents</display-name>
       <web-resource-collection>
       <web-resource-name>XHTML</web-resource-name>
       <url-pattern>*.xhtml</url-pattern>
       <http-method>GET</http-method>
       <http-method>POST</http-method>
       </web-resource-collection>
       <auth-constraint>
       <role-name>admin</role-name>
       </auth-constraint>
       </security-constraint>
       <login-config>
       <auth-method>BASIC</auth-method>
       <realm-name>testdbRealm</realm-name>
       </login-config>
       <security-role>
       <role-name>admin</role-name>
       </security-role>
      


      And according to the Seam doc I set the jaas-config-name property in the components.xml file:
      <security:identity authenticate-method="#{authenticator.authenticate}"
       jaas-config-name="testdbRealm"/>
      



      Now I have the following behavior:
      The application deploys and works, the *.xhtml pages are displayed but application is not asking for authorization. The database connection is set with the default user and pwd provided in the login-config.xml file (dumy, dumy_pwd).

      When I try to remove the default user and pwd from the login-config.xml file:
      <application-policy name = "testdbRealm">
       <authentication>
       <login-module code = "org.jboss.resource.security.CallerIdentityLoginModule" flag = "required">
       <module-option name = "managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=dbtestDatasource</module-option>
       </login-module>
       </authentication>
      </application-policy>
      


      then I have errors during deployment because the database connection can't be created (I'm not sure why - think that hibernate try to open the database during the deployment to do its mapping job). I see in server logs that CallerIdentityLoginModule is used.

      I stick on this problem and don't know how finish seting up things to enforce the behavior I write about on the beginning. Do I have to call CallerIdentityLoginModule directly from my application?

      I'm trying to resolve this issue for quite a long time. I'm not the JBoss and J2EE specialist (yet) (I'm the one who believed that building application's with JBoss + Seam combo is simple and trying to follow) so I appreciate any help and explanations how this mechanism works very much.

      Best Regards


        • 1. Re: Passing current user identity to the back-end database

          I'm going to bounce you around. ;-)
          The problem you have is really a Seam problem.
          That's because you already solved the problem you were trying to solve.

          JCA SIDE

          The configuration you have looks correct to me,
          provided you are running in a context where somebody has logged in.

          You don't have a default user/password so the datasource will be unusable in
          other contexts.

          That means your JCA issue is resolved.

          SEAM SIDE

          You don't use the testDBRealm within Seam, you need to provide a real
          mechanism to validate users and passwords.

          The JCA policy is for the question "what user/password should I use to access the
          database?". Your answer is "use the subject established on the thread".

          The Seam policy is for the question "how do I know the user/password typed in
          by the user is correct?". Your answer such be a real validation mechanism
          NOT "use what is already established on thread" which is most likely nothing. :-)

          This real policy will establish the subject on the thread.

          WHY THIS IS REALLY A SEAM/HIBERNATE/EJB3 QUESTION

          Your real problem is that there is some initialization
          during deployment. This runs on the deployment thread.

          There has been no login on that thread.

          You don't have a default user/password for such contexts so it is going to fail.

          If you don't want to specify a default then you need some hook or configuration
          where you can say "during deployment I want you to login as this user/password".

          • 2. Re: Passing current user identity to the back-end database

            One "belt and braces" way to do it (if you want further guidance ask in the security forum)
            is to not deploy your application via hot deployment.

            Instead you would deploy an mbean that does the deployment programmatically.
            e.g. something like (pseudo code)

            public class DeployWebApp implements DeployWebAppMBean
            {
             public void start() throws Exception
             {
             loginUsingClientLoginModule(user, password);
             try
             {
             // really a JMX invocation
             MainDeployer.deploy(urlToWebApp);
             }
             finally
             {
             logout();
             }
             }
            
             public void stop() throws Exception
             {
             // Really JMX
             MainDeployer.undeploy(urlToWebApp);
             }
            }
            


            But there's some subtle issues like making your mbean
            depend on the JBossWEB (Tomcat) deployer so it doesn't try to deploy the url
            before Tomcat is available.

            • 3. Re: Passing current user identity to the back-end database
              sztank

              I catch the policy question-answer thing, thanks:-) Good to hear that I'm step further.

              "adrian@jboss.org" wrote:

              You don't have a default user/password for such contexts..

              Where can I set default user/password that can be used during deployment? In the datasource file:
              <datasources>
               <local-tx-datasource>
               <jndi-name>dbtestDatasource</jndi-name>
               <connection-url>jdbc:postgresql:dbtest</connection-url>
               <driver-class>org.postgresql.Driver</driver-class>
               <security-domain>testdbRealm</security-domain>
               <user-name>deployment_usr</user-name>
               <password>deployment_pwd</password>
               </local-tx-datasource>
              </datasources>
              


              What about the name/password from the application-policy it can't be used in the deployment context?
              <application-policy name = "testdbRealm">
               <authentication>
               <login-module code = "org.jboss.resource.security.CallerIdentityLoginModule" flag = "required">
               <module-option name = "userName">dumy</module-option>
               <module-option name = "password">dumy_pwd</module-option>
               <module-option name = "managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=dbtestDatasource</module-option>
               </login-module>
               </authentication>
              </application-policy>
              





              • 4. Re: Passing current user identity to the back-end database

                On the application policy.

                The datasource properties and the createConnection(user, password)
                are ignored if you are using container managed security.

                Confusing, but It's in the JCA spec. :-)

                • 5. Re: Passing current user identity to the back-end database
                  sztank

                  Ok. Thanks a lot!

                  "adrian@jboss.org" wrote:

                  The Seam policy is for the question "how do I know the user/password typed in
                  by the user is correct?". Your answer such be a real validation mechanism
                  NOT "use what is already established on thread" which is most likely nothing. :-)

                  This real policy will establish the subject on the thread.

                  By the way, I was hoping that the following declaration in the Seam components.xml file ensure real validation mechanism and also will tell the Seam to set the login subject on the thread :

                  <security:identity authenticate-method="#{authenticator.authenticate}"
                   jaas-config-name="testdbRealm"/>
                  


                  But I will try to explore this from the SEAM SIDE.

                  Best Regards!