1 2 Previous Next 20 Replies Latest reply on Jan 6, 2010 6:54 PM by gavin.king

    Producer method

    mcalpay

      Hello, I have this simple bean for security, handling login, logout;


      @SessionScoped
      @Named("current")
      public class Current implements Serializable {
      
          private User user = ANONYMOUS;
          
          private static final User ANONYMOUS = new User("Anonymous");
      
          public User getUser() {
              return user;
          }
      
          public void logout() {
              this.user = ANONYMOUS;
          }
      
          public String checkLogin(User user) {
              if("testus".equals(user.getName())) {
                  this.user = user;
                  return "/index";
              }
              return "";
          }
      
          @Produces
          @RequestScoped
          @Principal
          @Named("principal")
          private User getPrincipal() {
              return user;
          }
      
      }



      What it does is user logins with the checkLogin method. If the pass is correct user field is assigned the submitted user. Then the getPrincipal producer method exposes this user with the @Produces, @RequestScoped and enables it accessible with ${principal} EL. However the user I got is always the anonymous user. This works however :



          @Produces
          @RequestScoped
          @Principal
          @Named("principal")
          private User getPrincipal(Current current) {
              return current.getUser();
          }



      Shouldn't the first example work ?
      I am working on Glassfish V3 env.
      Thanks.



        • 1. Re: Producer method
          nickarls

          Show the xhtml, how are you calling checkLogin etc?


          Have you debugged/outputted to see that you are are seeing the correct instances of the principal?


          • 2. Re: Producer method
            mcalpay

            this is how checkLogin is called :


            <h:body>
                <div>
                    <h:form>
                        User : <h:inputText value="#{login.name}"/> 
                        Password : <h:inputText value="#{login.name}"/>
                        <h:commandButton value="Login" action="#{current.checkLogin(login)}"/>
                    </h:form>
                </div>
            </h:body>



            login is a request scoped User bean.
            current is the bean on the first example


            this is how principal is displayed :



            <div>#{principal.name}</div>





            • 3. Re: Producer method
              nickarls

              What is user.getName() at the beginning of checkLogin()?

              • 4. Re: Producer method
                mcalpay

                Its the users input as entered on the :


                <h:inputText value="#{login.name}"/> 



                • 5. Re: Producer method
                  nickarls

                  I mean, what does it output? Trying to see if the inputted name has stuck or not.

                  • 6. Re: Producer method
                    mcalpay

                    It stucks. If the user enters testus it navigates to the index.html if not it stays on the login page

                    • 7. Re: Producer method
                      nickarls

                      Well, every time you reference #{principal} directly, you are going to get a fresh, request scoped principal from your producer. So it's no good for checking the logged-in-user at a later point.

                      • 8. Re: Producer method
                        mcalpay

                        changed the line :


                        this.user = user;



                        to assign a clone object.


                        Besides from that as far as I can understand what happens is, producer method doesn't get executed on the sessionscoped bean, rather It gets executed on a separate copy...

                        • 9. Re: Producer method
                          gavin.king

                          Huh? What is this line for??


                          if("testus".equals(user.getName()))



                          That looks bizarrely wrong.

                          • 10. Re: Producer method
                            gavin.king

                            Nicklas Karlsson wrote on Jan 05, 2010 14:44:


                            Well, every time you reference #{principal} directly, you are going to get a fresh, request scoped principal from your producer. So it's no good for checking the logged-in-user at a later point.


                            I don't think so. The produced User is coming from an instance variable of a @SessionScoped bean. So it is effectively session scoped. In fact, the @RequestScoped annotation on the producer method is in this case totally superfluous.

                            • 11. Re: Producer method
                              gavin.king

                              Murat Can ALPAY wrote on Jan 05, 2010 15:58:


                              changed the line :

                              this.user = user;



                              to assign a clone object.


                              Why?



                              Besides from that as far as I can understand what happens is, producer method doesn't get executed on the sessionscoped bean, rather It gets executed on a separate copy...


                              No, that's definitely not true. Spec 5.5.4 says that the container must invoke the producer method on a contextual instance of the bean which declares the method, where contextual instance is defined in 6.5.2.

                              • 12. Re: Producer method
                                alin.heyoulin.qq.com
                                
                                Before login the session @Produces user produce a instance. It's Anonymous copy. So you can try
                                
                                @SessionScoped
                                @Named("current")
                                public class Current implements Serializable {
                                
                                    private User user = ANONYMOUS;
                                    
                                    private static final User ANONYMOUS = new User("Anonymous");
                                    @Inject @Principal puser;
                                    public User getUser() {
                                        return user;
                                    }
                                
                                    public void logout() {
                                        this.user = ANONYMOUS;
                                    }
                                
                                    public String checkLogin(User user) {
                                        if("testus".equals(user.getName())) {
                                            this.puser = user;
                                            return "/index";
                                        }
                                        return "";
                                    }
                                
                                    @Produces
                                    @RequestScoped
                                    @Principal
                                    @Named("principal")
                                    private User getPrincipal() {
                                        return user;
                                    }
                                
                                }
                                


                                • 13. Re: Producer method
                                  nickarls

                                  Is there a problem in both the username and password binding to the name from the UI inputs? One would think the submit with a blank password would end up overwriting the name.

                                  • 14. Re: Producer method
                                    nickarls

                                    Or something with the EL?


                                    You start out with the user being ANONYMOUS in current. The producer returns it to the UI layer for the input fields to bind to (although both bind to the name). Then the button is clicked. The producer is called again to get the parameter for the method (although it shouldn't matter since it always returns the user field in current). So any passing in of the user (and assigning if login is successful) as a method parameter is really of no effect since we are always dealing with the instance in current.


                                    So I would understand a problem of it being non-ANONYMOUS at the wrong point but don't get it how it manages to remain anonymous...

                                    1 2 Previous Next