7 Replies Latest reply on Jul 8, 2002 6:06 PM by Torsten Schlumm

    Database Login Module

    Chad Lavy Newbie

      I know that this is probably a complete newbie question, but...

      I am using jboss-3.0.0_tomcat-4.0.3

      I am trying to write a web application that retrieves its database connnection using a jndi lookup from jboss. We are not going to use a hidden db id and login to create the connection. (i.e. the hardcoded username and password in the service.xml) Instead, we are going to use the user supplied name and password. Access to the web application is dictated by an individuals' access rights to the database itself.

      I have seen in the db2-service.xml that comes with jboss, mention of using JAAS and a login-conf file. I have also seen mention of a "Database Login Module" in the forum postings. (This has the sound of what I need.) What I am having problems with is the connecting of the dots. What do I need to do to utilize the DB2 usernames and passwords?

      Could someone point me to a resource that will give me a clear picture of what exactly I need to do?

      Thank You,
      Chad Lavy

        • 1. Re: Database Login Module
          Aaron Rustad Newbie

          I have having the same problem...unfortunatly, people don't seem to want to help. Here is what I have so far, hopefully we can figure this out together.

          Basically, I am using the oracle-service.xml example, modified for my needs, it looks like this:

          bcgasadmin

          <depends optional-attribute-name="ManagedConnectionFactoryName">
          <!--embedded mbean-->


          BCGasDS



          <config-property name="ConnectionURL" type="java.lang.String">jdbc:oracle:thin:@cgybcgasserv1:1521:gcprod</config-property>
          <config-property name="DriverClass" type="java.lang.String">oracle.jdbc.driver.OracleDriver</config-property>
          <!--set these only if you want only default logins, not through JAAS -->
          <config-property name="UserName" type="java.lang.String">SAIGON</config-property>
          <config-property name="Password" type="java.lang.String">SAIGON</config-property>





          From what I understand, the SecurityDomainJndiName tag should map to your login-config.xml. This is how mine looks:


          <application-policy name = "bcgasadmin">

          <login-module code = "com.bcgas.app.security.auth.spi.GasDatabaseServerLoginModule"
          flag = "required">
          <module-option name = "dsJndiName">java:/BCGasDS</module-option>
          <module-option name = "principalsQuery">SELECT password, active, login_attempts FROM Security_User WHERE security_user_id=?</module-option>
          <module-option name = "rolesQuery">SELECT role_id, role_group FROM Roles WHERE security_user_id=?</module-option>
          <module-option name = "activeQuery">SELECT active, login_attempts FROM Security_User WHERE security_user_id=?</module-option>
          <module-option name = "updateActiveQuery">UPDATE Security_User SET active=?, update_user=?, update_date=? WHERE security_user_id =?</module-option>
          <module-option name = "updateLoginAttemptsQuery">UPDATE Security_User SET login_attempts=?, update_user=?, update_date=? WHERE security_user_id =?</module-option>
          <module-option name = "maxAttempts">5</module-option>
          </login-module>

          </application-policy>

          My GasDatabaseLoginModule extends DatabaseLoginModule, and I have tested it with DatabaseLoginModule, but it still won't work.

          When deploying, I get to the part where the actual EJBs are being deployed and I get this part of the stack trace:

          jboss.management.single:J2EEApplication=ldccp.ear,J2EEServer=Single,j2eeType=EJBModule,name=admin-ejb.jar
          2002-06-27 15:43:45,788 DEBUG [org.jboss.management.j2ee.J2EEManagedObject] preDeregister(), parent: jboss.management.single:J2EEServer=Single,j2eeType=J2EEApplication,name=ldccp.ear
          2002-06-27 15:43:45,798 ERROR [org.jboss.ejb.EjbModule] Initialization failed
          java.lang.SecurityException: Invalid authentication attempt, principal=null
          at org.jboss.resource.connectionmanager.BaseConnectionManager2.getSubject(BaseConnectionManager2.java:707)
          at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:531)
          at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:812)
          at org.jboss.resource.adapter.jdbc.local.LocalDataSource.getConnection(LocalDataSource.java:102)
          at org.jboss.ej.......


          I don't know why it is failing here. When I look at JNDIView in the admin app (http://localhost:8082), I see that bcgasadmin has been bound to java:/jaas/bcgasadmin.


          I have no Idea what is going wrong here. I have been reading the QuickStart pdf, the documentaion, these forums, the mailing list, and no one can give me a definitive answer as to what is going on!

          Please JBoss people...I don't want to go back to Oracle 9iAS (orion).....help a guy out!

          Thanks!
          BCOT.

          • 2. Re: Database Login Module
            Chad Lavy Newbie

            I am completely floundering with the JAAS concept. I haven't been able to find a single snippit of documentation for JBoss that ties it all together. Where did you find the quick start pdf?

            How did you get as far as you did? I can't even find any info on where this login-config.xml should be deployed. How did you figure out how to use the DatabaseLoginModule?

            On the bright side, I was able to get the connection going from the web app. I used something like the following in a helper bean:

            Context ic = new InitialContext();
            DataSource ds = (javax.sql.DataSource)ic.lookup("java:/DB2DS");
            Connection dbconn = ds.getConnection(supplieduname, suppliedpw);

            This might not help you since it is not using JAAS. I would like to figure out the whole JAAS thing, it seems much more robust and elegant.


            I don't know if it helps, but the example in the db2-service.xml names the principal explicitly instead of as a query:

            &lt;application-policy name = "DB2DbRealm"&gt;
            &lt;authentication&gt;
            &lt;login-module code = "org.jboss.resource.security.ConfiguredIdentityLoginModule" flag = "required"&gt;
            &lt;module-option name = "principal"&gt;yourprincipal&lt;/module-option&gt;
            &lt;module-option name = "userName"&gt;yourusername&lt;/module-option&gt;
            &lt;module-option name = "password"&gt;yourpassword&lt;/module-option&gt;
            &lt;module-option name = "managedConnectionFactoryName"&gt;jboss.jca:service=LocalTxCM,name=DB2DS&lt;/module-option&gt;
            &lt;/login-module&gt;
            &lt;/authentication&gt;
            &lt;/application-policy&gt;

            • 3. Re: Database Login Module
              Aaron Rustad Newbie

              Yes, this is very frustrating. Anyway, you can find the QuickStart guide at:

              http://sourceforge.net/projects/jboss/

              Look under files, it lists a PDF. Good luck!

              • 4. Re: Database Login Module
                mjeffrey Newbie

                I'm not an expert on this but here goes.

                I think I understand your confusion - you want users to login using their DATABASE login and password. Unfortunately (or fortunately) It doesn't work that way. Application servers use pooled connections with a single login for performance (and other) reasons and the authentication is done by another means (or often not at all for public readonly data).
                You can optionally protect EJBs : JAAS can be used to perform the authentication and authorization for this security. But even if you do this authentication using the supplied Database Login Module your beans are NOT accessing the database through this login - they must access it through the username/password defined for the resource.

                Hope this helps.
                Mark

                • 5. Re: Database Login Module
                  Torsten Schlumm Newbie

                  Well BCOT,

                  F*CK, F*CK, F*CK ... I'm so close to shoot myself ... in the head ... actually ... :-(

                  So, I've had the exact same problem for the last two days - and I (at least I think so) got
                  the hang of it. Of course it could be complete nonsense.

                  My login-config.xml looked like this:


                  ...
                  <application-policy name = "fooDBRealm">

                  <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required">
                  <module-option name = "dsJndiName">java:/fooDS</module-option>
                  </login-module>

                  </application-policy>
                  ...



                  the fooDS-service.xml like that:



                  fooDBRealm

                  <depends optional-attribute-name="ManagedConnectionFactoryName">


                  fooDS



                  <config-property name="ConnectionURL" type="java.lang.String">jdbc:mysql://localhost:3306/foo</config-property>
                  <config-property name="DriverClass" type="java.lang.String">org.gjt.mm.mysql.Driver</config-property>
                  <config-property name="UserName" type="java.lang.String">fooDSUser</config-property>
                  <config-property name="Password" type="java.lang.String">fooDSPass</config-property>



                  <depends optional-attribute-name="OldRarDeployment">jboss.jca:service=RARDeployment,name=JBoss LocalTransaction JDBC Wrapper



                  ...



                  This means (at least to me ... now):
                  - in login-config.xml 'fooDBRealm' gets configured based on the datasource 'fooDS'
                  - in fooDS-service.xml 'fooDS' gets configured as usual ... but ... the line
                  fooDBRealm
                  means the access to the 'fooDS' datasource is controlled by the 'fooDBRealm'

                  So - the 'fooDBRealm' is based on the datasource 'fooDS' and the access to 'fooDS'
                  is controlled by 'fooDBRealm'.

                  Sounds like some circular thing to me.

                  Solution: remove 'fooDBRealm' from
                  fooDS-service.xml

                  After that my app/beans deployed just fine.

                  I do hope this helps somehow. But it is the middle of the night over here - so it might all
                  be some kind of nonsense - sorry.

                  Cheers,
                  Torsten

                  PS:

                  Is your first name 'Big', 'BigCan' or 'BigCanOf' ???

                  • 6. Re: Database Login Module
                    Dirk Dreyer Newbie

                    Hi,

                    I had the same Problem and now it works fine.
                    First you must comment out the "SecurityDomainJndiName" this won't work (I don't know why):

                    <!--uncomment out this line if you are using the OracleDbRealm above
                    OracleRealm
                    -->


                    <depends optional-attribute-name="ManagedConnectionFactoryName">
                    <!--embedded mbean-->


                    OracleDS



                    <config-property name="ConnectionURL" type="java.lang.String">jdbc:oracle:thin:@laptop-dirk:1521:j2ee</config-property>
                    <config-property name="DriverClass" type="java.lang.String">oracle.jdbc.driver.OracleDriver</config-property>
                    <!--set these only if you want only default logins, not through JAAS -->
                    <config-property name="UserName" type="java.lang.String">cwp</config-property>
                    <config-property name="Password" type="java.lang.String">cwp</config-property>




                    Second you add two (I explain later why) application-policy to your login-config.xml like this:

                    <application-policy name = "OracleRealm">

                    <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 = "dsJndiName">java:/OracleDS</module-option>
                    <module-option name = "principalsQuery">select Passwort from Benutzer where login=?</module-option>
                    <module-option name = "rolesQuery">SELECT name, rollengruppe from benutzerrolle where oid in (select Benutzerrolle from benutzer_benutzerrolle where Benutzer in (select oid from Benutzer where login=?))</module-option>
                    </login-module>


                    </application-policy>

                    <application-policy name = "OracleRealm2">

                    <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 = "dsJndiName">java:/OracleDS</module-option>
                    <module-option name = "principalsQuery">select Passwort from Benutzer where login=?</module-option>
                    <module-option name = "rolesQuery">SELECT name, rollengruppe from benutzerrolle where oid in (select Benutzerrolle from benutzer_benutzerrolle where Benutzer in (select oid from Benutzer where login=?))</module-option>
                    <module-option name = "unauthenticatedIdentity">nobody</module-option>
                    </login-module>


                    </application-policy>

                    Third you add an security-domain tag to your jboss-web.xml and jboss.xml like this:

                    jboss.xml:
                    <?xml version="1.0" encoding="UTF-8"?>
                    <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 3.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_3_0.dtd">

                    <!-- All bean containers use this security manager by default -->
                    <security-domain>java:/jaas/OracleRealm2</security-domain>

                    <enterprise-beans>

                    <ejb-name>Benutzer</ejb-name>

                    ...

                    jboss-web.xml:
                    <?xml version="1.0"?>
                    <!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.3//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_3_0.dtd">

                    <jboss-web>
                    <security-domain>java:/jaas/OracleRealm</security-domain>
                    </jboss-web>

                    You see the two OracleRealms. In jboss-web.xml is the OracleRealm defined and in jboss.xml the OracleRealm2. This is for MessageDrivenBeans or the RunAs-Tag. Because MessageDrivenBeans have no Identity they use the unautheticatedIdentity in the login-config.xml. But if you have only one OracleRealm you login always with the unauthenticatedIdentity (whitout any Security like Username and Password).


                    I hope this will help ! :-) If someone want my XML-Files send an Email to Dirk.Dreyer@cosinex.com

                    • 7. Re: Database Login Module
                      Torsten Schlumm Newbie

                      >First you must comment out the "SecurityDomainJndiName" >this won't work (I don't know why):

                      Dirk,

                      See my previous post.
                      I think the SecurityDomainJndiName attribute means
                      the data source you define (declare) is controlled by
                      this realm. And therefore (in your case) OracleDS is
                      controlled by OracleRealm and because later on (in
                      login-config.xml) you say OracleRealm is based on
                      OracleDS (in the dsJndiName option) this thing has
                      to explode because:

                      OracleRealm depends on OracleDS
                      OracleDS depends on OracleRealm

                      At least that's what I worked out.

                      Mail back if I didn't make myself clear enough.

                      Cheers,
                      Torsten