5 Replies Latest reply on Aug 15, 2008 2:10 PM by Leandro Hermida

    Possible identity authenticate bug still with Seam 2.0.3.CR1

    Leandro Hermida Newbie

      Hi everyone,


      This has been driving me crazy... is there a bug with both Seam 2.0.2.GA and 2.0.3.CR1 that after a failed login attempt is made the authenticator.authenticate method will get called at every single page request and also gets called twice?


      I am debugging a very simple application with JBoss Tools and Eclipse and this is clearly what's happening and I don't understand why.  Everything is fine if I've never made a failed login attempt but once I do it once then after that if I even type in the browser any page URL I see that it calls the authenticator.authenticate method everytime and twice before even rendering the page!!


      I am using Seam with all EJBs no POJOs, could this be the problem?


      Thank you for any help,


      Leandro

        • 1. Re: Possible identity authenticate bug still with Seam 2.0.3.CR1
          Leandro Hermida Newbie

          Hello everyone again,


          I have made a simple example Seam Web Project in Eclipse and the SAME bug is still happening.  I am almost certain that this is a Seam bug.  I am using the latest Eclipse Europa and JBoss Tools with WTP patch and I have used the Seam Web Project wizard with EAR deployment to create the project scaffold.


          Can someone please help or verify for me that if you make your Authenticator bean an EJB stateless session bean that this bug exists?  This is very frustrating as a Seam newbie :(


          Here is my WEB-INF/components.xml:


          ?xml version="1.0" encoding="UTF-8"?>
          <components xmlns="http://jboss.com/products/seam/components"
                      xmlns:core="http://jboss.com/products/seam/core"
                      xmlns:persistence="http://jboss.com/products/seam/persistence"
                      xmlns:drools="http://jboss.com/products/seam/drools"
                      xmlns:bpm="http://jboss.com/products/seam/bpm"
                      xmlns:security="http://jboss.com/products/seam/security"
                      xmlns:transaction="http://jboss.com/products/seam/transaction"
                      xmlns:mail="http://jboss.com/products/seam/mail"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                      xsi:schemaLocation=
                          "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd 
                           http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.0.xsd 
                           http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.0.xsd
                           http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.0.xsd
                           http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd
                           http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.0.xsd
                           http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.0.xsd
                           http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd">
          
             <core:init debug="true" jndi-pattern="@jndiPattern@"/>
               
             <core:manager concurrent-request-timeout="500" 
                           conversation-timeout="120000" 
                           conversation-id-parameter="cid"
                           parent-conversation-id-parameter="pid"/>
             
             <transaction:ejb-transaction/>
          
             <drools:rule-base name="securityRules">
                 <drools:rule-files>
                     <value>/security.drl</value>
                 </drools:rule-files>
             </drools:rule-base>
          
             <security:identity security-rules="#{securityRules}" authenticate-method="#{authenticator.authenticate}"/>
                
          </components>
          



          Here is my code:


          package org.sysfusion.session;
          
          import javax.ejb.Local;
          
          @Local
          public interface Authenticator
          {
          
              public boolean authenticate();
              public boolean logout();
          
          }
          



          package org.sysfusion.session;
          
          import org.jboss.seam.security.Identity;
          import org.sysfusion.entity.User;
          import org.jboss.seam.annotations.Name;
          import javax.ejb.Stateless;
          
          @Stateless
          @Name("authenticator")
          public class AuthenticatorBean implements Authenticator
          {
              // ------ Session Context Injection ------
              
              @javax.annotation.Resource
              protected javax.ejb.SessionContext context;
          
              // ------ Persistence Context Definitions --------
              
              /**
               * Inject persistence context sysfusion     
               */
              @javax.persistence.PersistenceContext(unitName = "sysfusion")    
              protected javax.persistence.EntityManager emanager;
          
              // ------ DAO Injection Definitions --------
          
              /**
               * Inject DAO UserDao
               */
              @javax.ejb.EJB
              private org.sysfusion.session.UserDao userDao;
          
              // --------- Attribute Definitions ------------
              
              /**
               * The user property
               */
              @org.jboss.seam.annotations.Out(required = false)
              protected org.sysfusion.entity.User user;
              
              /**
               * The log property
               */
              @org.jboss.seam.annotations.Logger
              protected org.jboss.seam.log.Log log;
              
              // -------- Business Methods --------------
              
              public boolean authenticate()
              {
                   try
                   {
                       User existingUser = userDao.findByUsernameAndPassword
                       (
                           Identity.instance().getUsername(),
                           Identity.instance().getPassword()
                       );
                            
                       user = existingUser;
                       log.info("Successfully authenticated user: " + user.getUsername());
                      
                       // load security roles
                       
                       return true;
                   }
                   catch (UserDaoException ex)
                   {
                       return false;
                   }
              }
              
              public boolean logout()
              {
                   Identity.instance().logout();
                   if (user != null) user = null;
                   return true;
              }
          
          
              // -------- Lifecycle Callback Implementation --------------
              
          }
          


          • 2. Re: Possible identity authenticate bug still with Seam 2.0.3.CR1
            Leandro Hermida Newbie

            Hello again,


            Guess what?


            I upgraded all my Seam jars to 2.1.0.A1 and during debugging of the example above it completely goes away!


            To be frank I wish someone would have told me that this quite serious bug exists in the latest production versions of Seam and that everyone it bascially using 2.1.0.A1.  I could not find that statement in the forums or in JIRA.


            Leandro

            • 3. Re: Possible identity authenticate bug still with Seam 2.0.3.CR1
              Shane Bryzak Master

              Try calling Identity.setPassword(null) in your authenticator method if authentication fails.  That should prevent it from attempting a quiet login for subsequent requests.

              • 4. Re: Possible identity authenticate bug still with Seam 2.0.3.CR1
                Pete Muir Master

                Nonsense, Seam 2.0.2.GA was released after Seam 2.1.0.A1!

                • 5. Re: Possible identity authenticate bug still with Seam 2.0.3.CR1
                  Leandro Hermida Newbie

                  Hello,


                  Thank you for the suggestion - setting the password to null after a failed login prevents the silent attempts in Seam 2.0.2.SP1.


                  This should be added to the Seam Documentation, I just looked again and there is no mention of the fact that if Identity has something in the password property that on every request it will silently try to authenticate.  If you look at the code example in the Seam 2.0.2.SP1 docs it does not show that you have to do this (see below).


                  @Name("authenticator")
                  public class Authenticator {
                  
                     @In EntityManager entityManager;
                  
                     public boolean authenticate() {
                        try
                        {
                           User user = (User) entityManager.createQuery(
                              "from User where username = :username and password = :password")
                              .setParameter("username", Identity.instance().getUsername())
                              .setParameter("password", Identity.instance().getPassword())
                              .getSingleResult();
                           if (user.getRoles() != null)
                           {
                              for (UserRole mr : user.getRoles())
                                 Identity.instance().addRole(mr.getName());
                           }
                           return true;
                        }
                        catch (NoResultException ex)
                        {
                           return false;
                        }
                     }
                  }
                  



                  It should read:


                  catch (NoResultException ex)
                  {
                      Identity.setPassword(null);
                      return false;
                  }