13 Replies Latest reply on Jan 7, 2011 8:40 AM by morfiel

    Seam Identity Management - User properties

    joblini

      Hello,


      I am in the process of integrating the new Seam Identity Management API.


      Currently, it is possible to define the User properties FirstName and LastName :


      public boolean createUser(String name, String password, String firstname, String lastname)



      Are there any plans to make the API more general so that other properties can be stored with a User, for example,



      • Secret Question, Answer

      • Email

      • etc.



      I'm thinking of something like:


      public boolean createUser(String name, String password, Map properties)
      




      Thanks!


        • 1. Re: Seam Identity Management - User properties
          shane.bryzak

          If you're using JpaIdentityStore then you can simply write an observer for org.jboss.seam.security.management.userCreated - the user object will be passed as an event parameter.

          • 2. Re: Seam Identity Management - User properties
            joblini

            The observer is not useful in this case.  It gives me access to the user object, but not to the properties I wish to associate with the user. 


            I am attempting to implement the following method by extending IdentityManager and JPAIdentityStore.


            public boolean createUser(String name, String password, Map properties)






            • 3. Re: Seam Identity Management - User properties
              joblini

              Also, the observer can not be used in the case because the additional properties must be set on the user before the user can be persisted (they are mapped to not-null columns in the database).


              According to the Seam reference document (15.4.2)



              This identity store allows for users and roles to be stored inside a relational database. It is designed to be as unrestrictive as possible in regards to database schema design, allowing a great deal of flexibility in the underlying table structure.

              Currently, no not-null columns can be present in the users table, apart from username, password, firstname, lastname.


              • 4. Re: Seam Identity Management - User properties
                shane.bryzak

                My apologies, it's the org.jboss.seam.security.management.prePersistUser event that gives you access to the entity before it is persisted to the database.  Which properties can't you set this way?

                • 5. Re: Seam Identity Management - User properties
                  joblini

                  The problem is in obtaining the values to be set.



                  @Observer("org.jboss.seam.security.management.prePersistUser")
                  onPrePersist(User user) {
                  }
                  



                  OK, I now have the user object, and that's all I have.  How do I get the values to be set? I have to define them as class members, which is, IMHO, rather convoluted.  Also, this locks me into the JPA provider.  What if I want to switch to LDAP or some another provider?  I would then have to rewrite all of this stuff.


                  That is why I think it would be great to have an interface like


                  createUser(name, password, OtherProperties)



                  As an aside, I also find the listUsers function is very limited, since it only lists the string valued user name, not the user object.  So again, we have to write custom code for JPA or LDAP or whatever.


                  Maybe I misunderstood but I thought that the API would make the provider transparent, at least for basic operations such as creating and managing users.




                  • 6. Re: Seam Identity Management - User properties
                    shane.bryzak

                    The problem with specifying a map of additional properties is how they're applied to the underlying identity store.  Let's take JpaIdentityStore for example - your own requirements may be that you simply want to interpret the contents of the map as bean properties that are applied to the entity value being persisted.  However, someone else may wish to create a whole graph of related entities based on the user object, in which case a simply map just won't be sufficient.


                    The best way to cover all possibilities is to simply provide the entity object before it is persisted, from which you then have the total freedom to do what you like with.  As for where you get the property values from, well surely these should already be in scope within the component that you creating the user from.

                    • 7. Re: Seam Identity Management - User properties
                      joblini

                      I see your point.  Thanks for taking the time to reply.  I have done as you suggested, using @Observer.
                      Here is my code, perhaps someone else will find it useful.


                      import static org.jboss.seam.ScopeType.EVENT;
                      import static org.jboss.seam.annotations.Install.APPLICATION;
                      
                      import org.agritrace.model.security.User;
                      import org.jboss.seam.annotations.Install;
                      import org.jboss.seam.annotations.Name;
                      import org.jboss.seam.annotations.Observer;
                      import org.jboss.seam.annotations.Scope;
                      import org.jboss.seam.annotations.intercept.BypassInterceptors;
                      
                      @Scope(EVENT)
                      @Name("org.jboss.seam.security.identityManager")
                      @Install(precedence = APPLICATION)
                      @BypassInterceptors
                      public class IdentityManager extends org.jboss.seam.security.management.IdentityManager {
                      
                           public static final String EVENT_USER_CREATED = "org.jboss.seam.security.management.userCreated";
                           public static final String EVENT_PRE_PERSIST_USER = "org.jboss.seam.security.management.prePersistUser";
                      
                           User user;
                      
                           public boolean createUser(User user) {
                                this.user = user;
                                return super.createUser(user.getUsername(), user.getPassword());
                           }
                      
                           @Observer(EVENT_PRE_PERSIST_USER)
                           public void onPrePersist(User user) {
                                user.setLanguage(this.user.getLanguage());
                           }
                      
                           @Observer(EVENT_USER_CREATED)
                              public void onUserCreated(User user) {
                                // could do post persist stuff here
                           }
                      
                      }
                      



                      Call it ...


                          @In(create=true)
                          IdentityManager identityManager;
                      
                                User user = new User();
                                user.setUsername("obama");
                                user.setPassword("demo");
                                user.setLanguage("en");
                                
                                boolean success = identityManager.createUser(user);
                      
                      



                      • 8. Re: Seam Identity Management - User properties
                        shane.bryzak

                        That solution will work, however there's no need to extend IdentityManager - just put your event observers in the component that you're calling from.

                        • 9. Re: Seam Identity Management - User properties
                          joblini

                          Right, it would work without extending Identify Manager.


                          I choose to extend Identity Manager because I want to hide the details from the caller.  We are developing a software package and want to be able to accommodate various security providers, hopefully with no changes to the code, other than writing a custom provider (for example, implementing IdentityStore. 


                          At the moment, it seems like overkill to develop yet another layer, ie IdentityManagerFacade.  I could be mistaken, as I am still in the process of learning about the new Seam Identity Management capabilities ...


                          Thanks again!




                          • 10. Re: Seam Identity Management - User properties
                            shidmei

                            Hi, the @Observer doesn't seem to work in my code below:



                            @In
                            private IdentityManager identityManager;
                                    
                            private Role newRole = new Role();
                                    
                            public void addRole(){
                                    try{
                                            identityManager.createRole(newRole.getRolename());
                                                    
                                    }catch (Exception e) {
                                            log.info("ERROR CREATING NEW USER ROLE: #0", e.getMessage());
                                    }               
                            }
                                    
                            @Observer("org.jboss.seam.security.management.prePersistUserRole")
                            public void onPrePersistUserRole(Role role) {
                                    log.info("in observer");
                            }
                            



                            The log in observer never printed out in Terminal.
                            What's wrong? Please help.

                            • 11. Re: Seam Identity Management - User properties
                              joblini

                              Hello,


                              Looking at the code posted:



                              • the value of Rolename has not been initialized.




                              • any exception is being swallowed.




                              • createRole returns a bolean value which is not being checked.



                              PS. A new post should have been started for this question.

                              • 12. Re: Seam Identity Management - User properties
                                tausuahmed

                                Hello,



                                How do we update user properties since there is no observer such as org.jboss.seam.security.management.preUpdateUser







                                • 13. Re: Seam Identity Management - User properties
                                  morfiel

                                  Hello together,


                                  sorry for re-opening that dead thread, but I think the subject is still interesting. I implemented a user class (UserAccount) to use for identification and realized some extensions using the proposed observer pattern.


                                  However, from the way I see it, using persistnace observers is de facto bypassing the identityManager. So the whole thing will break down as soon as I try to replace JpaIdentityStore with, say, Ldap. As having the freedom to exchange identityStores is the signle reasonable point of the whole security architecture with identityManager, it basically renders the whole system useless.


                                  Or am I missing a point?


                                  best regards
                                      Tim