9 Replies Latest reply on Mar 1, 2007 11:08 PM by changemylife

    Latest JAAS Tutorial for Database communication

    nkoranne

      Hello,

      Can you please give me pointer to the latest JAAS tutorial which has the inetraction with the database for authentication and authorization?
      I am using JBoss 4.0.3SP1.

      Also if you can give me the pointer of jGuard Tutorial, then it would be easy for me to compare the JAAS vs. JGuard


        • 1. Re: Latest JAAS Tutorial for Database communication
          zzztimbo

          why hasn't anyone replied to this post? i have a similar interest in a good tutorial on setting up JAAS in JBoss.

          • 2. Re: Latest JAAS Tutorial for Database communication
            smeaggie

            don't know about jGuard, but this is JAAS with database login (a real quicky tho, feel free to ask more).

            1) setup the connection to the database. put a "database-ds.xml" file in the deploy directory wich contains something like:

            <datasources>
             <local-tx-datasource>
             <jndi-name>exampleDS</jndi-name>
             <connection-url>jdbc:postgresql://127.0.0.1:5432/example</connection-url>
             <driver-class>org.postgresql.Driver</driver-class>
             <user-name>ex</user-name>
             <password>_______</password>
             <min-pool-size>5</min-pool-size>
             <max-pool-size>20</max-pool-size>
             <metadata>
             <type-mapping>PostgreSQL 7.2</type-mapping>
             </metadata>
             </local-tx-datasource>
            </datasources>
            

            make sure you enter the correct driver, connection string etc. Now open login-config.xml in the server's conf/ directory. you need to define a security domain here. add this to the file:
            <application-policy name = "exampleDomain">
             <authentication>
             <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required">
             <module-option name = "unauthenticatedIdentity">guest</module-option>
             <module-option name = "dsJndiName">java:/exampleDS</module-option>
             <module-option name = "principalsQuery">SELECT PASSWD FROM USERS WHERE USERID=?</module-option>
             <module-option name = "rolesQuery">SELECT ROLEID, 'Roles' FROM ROLES WHERE USERID=?</module-option>
             </login-module>
             </authentication>
            </application-policy>
            

            note the definition "exampleDomain" and how the dsJndiName is set to java:/exampleDS. exampleDS comes from the database connection definition above! the two queries in this file mean the following: the principalsQuery should return the password of the user where userid is the name the user entered in the login form. The rolesQuery must return all roles associated with the username. So it's time to create two tables in your database, with at least this info:
            table USERS
            +-------------------------------------+
            | userid | passwd |
            +-------------------------------------+
            | test | secret |
            +-------------------------------------+
            
            table ROLES
            +-------------------------------------+
            | userid | roleid |
            +-------------------------------------+
            | test | admin |
            | test | manager |
            +-------------------------------------+
            

            (don't mind the ascii art)

            we've created a user "test" with the password "secret" and the roles "admin" and "manager".

            time to secure the web application, open up jboss-web.xml (from the WEB-INF directory) and put this in it:
            <?xml version="1.0" encoding="UTF-8"?>
            <jboss-web>
             <security-domain>java:/jaas/exampleDomain</security-domain>
             <context-root>/example</context-root>
            </jboss-web>
            

            this sets the security domain for the web application to "exampleDomain" wich is declared in the login-config.xml above! jboss now knows wich login module configuration applies to this application.
            now edit web.xml (also in the WEB-INF directory) and add this:
             <security-constraint>
             <display-name>manager</display-name>
             <web-resource-collection>
             <web-resource-name>manager_pages</web-resource-name>
             <description/>
             <url-pattern>/manager/*</url-pattern>
             <http-method>GET</http-method>
             <http-method>POST</http-method>
             <http-method>HEAD</http-method>
             <http-method>PUT</http-method>
             <http-method>OPTIONS</http-method>
             <http-method>TRACE</http-method>
             <http-method>DELETE</http-method>
             </web-resource-collection>
             <auth-constraint>
             <description/>
             <role-name>manager</role-name>
             </auth-constraint>
             <user-data-constraint>
             <description/>
             <transport-guarantee>NONE</transport-guarantee>
             </user-data-constraint>
             </security-constraint>
            
             <security-constraint>
             <display-name>admin</display-name>
             <web-resource-collection>
             <web-resource-name>admin_pages</web-resource-name>
             <description/>
             <url-pattern>/admin/*</url-pattern>
             <http-method>GET</http-method>
             <http-method>POST</http-method>
             <http-method>HEAD</http-method>
             <http-method>PUT</http-method>
             <http-method>OPTIONS</http-method>
             <http-method>TRACE</http-method>
             <http-method>DELETE</http-method>
             </web-resource-collection>
             <auth-constraint>
             <description/>
             <role-name>admin</role-name>
             </auth-constraint>
             <user-data-constraint>
             <description/>
             <transport-guarantee>NONE</transport-guarantee>
             </user-data-constraint>
             </security-constraint>
            
             <login-config>
             <auth-method>FORM</auth-method>
             <realm-name>example</realm-name>
             <form-login-config>
             <form-login-page>/login.html</form-login-page>
             <form-error-page>/login_error.html</form-error-page>
             </form-login-config>
             </login-config>
            
             <security-role>
             <description/>
             <role-name>admin</role-name>
             </security-role>
             <security-role>
             <description/>
             <role-name>manager</role-name>
             </security-role>
            

            this defines two security constraints: one for everything behind /manager (where only users with the "manager" role are allowed) and one for admins, everything behind /admin.

            the login pages (login.html and login-error.html) should look like this:
            <html>
            <body>
             <form action="j_security_check" method="post">
             <input type="text" name="j_username"><br>
             <input type="password" name="j_password"><br>
             <input type="submit" value="login">
             </form>
            </body>
            </html>
            


            hope this helps!

            • 3. Re: Latest JAAS Tutorial for Database communication
              aleksab

              What about when you want to secure a client?

              I've added a policy to the conf/login-config.xml, which seems to work. It connects to the database, but the username is always null (found out by examining the mysql log)

              In the client i'm using a LoginContext, and i've included

              <login-module code="org.jboss.security.ClientLoginModule" flag="required" />
               <module-option name="restore-login-identity">true</module-option>
               </login-module>
              

              in the conf/login-config.xml like the FAQ says I must do in order for the authentication info propagating to the called component.

              But the principal (and password I assume) is never propagating.

              My client looks like this:
              LoginContext loginContext = new LoginContext("pn-login", new CallbackHandler());
               loginContext.login();
              
               Hashtable<String, String> env = new Hashtable<String, String>();
               env.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.NamingContextFactory");
               env.put(InitialContext.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
               env.put(InitialContext.PROVIDER_URL, "jnp://localhost:1099");
              
               Context ctx = new InitialContext(env);
               SecurityBean bean = (SecurityBean) ctx.lookup("SecurityBeanImpl/remote");
              


              When i call
              System.out.println("Unsecure string: " + bean.getSimpleString());
              


              i get this exception:
               javax.security.auth.login.FailedLoginException: No matching username found in Principals
              


              What am i doing wrong? Been struggling with this for some time now...

              • 4. Re: Latest JAAS Tutorial for Database communication
                smeaggie

                ah that's quiet another story, I described securing a web app, not ejb's. You must annotate the EJB's with the security domain and allowed roles, like this: (assuming you work with EJB3 that is)

                @Stateless()
                @SecurityDomain("exampleDomain")
                public class MyBean implements MyBeanRemote {
                 /**
                 * allowed to everyone
                 */
                 @PermitAll()
                 public String getSimpleString() {
                 return "unsecure";
                 }
                
                 /**
                 * Only 'admin' role allowed
                 */
                 @RolesAllowed({"Admin"})
                 public String getAdvancedString() {
                 return "secured";
                 }
                }

                I'm not experienced with remote clients, all my clients are local... Someone else has to fill in that part.

                • 5. Re: Latest JAAS Tutorial for Database communication
                  aleksab

                  Yeah, i've annotated the EJB with my security domain and allowed roles. This works, since the exception (with no matching username) is thrown.

                  If somebody know what I'm doing wrong with the client, please inform me. Just can not get the client to propagate the Jaas information to the EJB layer it seems.

                  • 6. Re: Latest JAAS Tutorial for Database communication
                    aleksab

                    Are there really nobody who can help me here?
                    Have posted numerous requests and searched the web without any luck.

                    • 7. Re: Latest JAAS Tutorial for Database communication
                      changemylife

                      Hi!
                      I have same problem. I wonder that some informations that user entered (username and passwd) were encoded ? Some informations that get from mySQL is plain text ! So they can't match !
                      Have any ideal ? Thanks!

                      • 8. Re: Latest JAAS Tutorial for Database communication
                        jaikiran

                         

                        "aleksab" wrote:
                        What about when you want to secure a client?

                        I've added a policy to the conf/login-config.xml, which seems to work. It connects to the database, but the username is always null (found out by examining the mysql log)

                        In the client i'm using a LoginContext, and i've included
                        <login-module code="org.jboss.security.ClientLoginModule" flag="required" />
                         <module-option name="restore-login-identity">true</module-option>
                         </login-module>
                        

                        in the conf/login-config.xml like the FAQ says I must do in order for the authentication info propagating to the called component.

                        But the principal (and password I assume) is never propagating.

                        My client looks like this:
                        LoginContext loginContext = new LoginContext("pn-login", new CallbackHandler());
                         loginContext.login();
                        
                         Hashtable<String, String> env = new Hashtable<String, String>();
                         env.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.NamingContextFactory");
                         env.put(InitialContext.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
                         env.put(InitialContext.PROVIDER_URL, "jnp://localhost:1099");
                        
                         Context ctx = new InitialContext(env);
                         SecurityBean bean = (SecurityBean) ctx.lookup("SecurityBeanImpl/remote");
                        


                        When i call
                        System.out.println("Unsecure string: " + bean.getSimpleString());
                        


                        i get this exception:
                         javax.security.auth.login.FailedLoginException: No matching username found in Principals
                        


                        What am i doing wrong? Been struggling with this for some time now...


                        Is your client a standalone application? Also can you post the trace logs of the security package (look at Q4 at http://wiki.jboss.org/wiki/Wiki.jsp?page=SecurityFAQ to see how it can be enabled)

                        • 9. Re: Latest JAAS Tutorial for Database communication
                          changemylife

                          Hi all!
                          Today, all things are ok (they worked!). My project is EJB3.0. Inside folder \server\default\conf, I add some informations:

                          <application-policy name = "DB-Domain">
                           <authentication>
                           <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule"
                           flag = "required">
                           <module-option name = "unauthenticatedIdentity">guest</module-option>
                           <module-option name = "dsJndiName">java:/DefaultDS</module-option>
                           <module-option name = "principalsQuery">SELECT PASSWD FROM USERS WHERE USERID=?</module-option>
                           <module-option name = "rolesQuery">SELECT ROLEID, 'Roles' FROM ROLES WHERE USERID=?</module-option>
                           </login-module>
                           </authentication>
                           </application-policy>

                          My jboss.xml :
                          <jboss>
                           <security-domain>DB-Domain</security-domain>
                           <enterprise-beans>
                           <session>
                           <ejb-name>ClientActionBean</ejb-name>
                           <resource-ref>
                           <res-ref-name>jdbc/DefaultDS</res-ref-name>
                           <jndi-name>java:/DefaultDS</jndi-name>
                           </resource-ref>
                           </session>
                           </enterprise-beans>
                          </jboss>

                          and ejb-jar.xml:
                          <enterprise-beans>
                           <session>
                           <ejb-name>ClientActionBean</ejb-name>
                           <resource-ref>
                           <res-ref-name>jdbc/DefaultDS</res-ref-name>
                           <res-type>javax.sql.DataSource</res-type>
                           <res-auth>Container</res-auth>
                           </resource-ref>
                           </session>
                          </enterprise-beans>
                           <assembly-descriptor>
                           <Security-role>
                           <role-name>doctor</role-name>
                           </Security-role>
                           <Security-role>
                           <role-name>nurse</role-name>
                           </Security-role>
                           <method-permission>
                           <role-name>doctor</role-name>
                           <method>
                           <ejb-name>ClientActionBean</ejb-name>
                           <method-name>getCallInfo</method-name>
                           </method>
                          ....

                          I use Eclipse to write client app, bean and package my bean enclose two file jboss.xml and ejb-jar.xml (inside META-INF). Restart server, and run client app!
                          Note: I installed Jboss server and mySQL on the machine 1(hostname:abc), and on the machine 2 (hostname:xxx). All things ok!
                          Hope this helps!!!!