9 Replies Latest reply on Sep 15, 2011 3:08 PM by baraber

    SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)

    baraber

      Hello :)
      I'm working with seam-security 3.1.0.Beta2 using JPAIdentityStore with hibernate and mysql under glassfish 3.1.


      I have to implements simple coarse-grained security based on group membership.
      Basically, I have a user named employe that is in group usine.
      Here is how I populate the database :




          @Transactional
          public void loadData(@Observes @Initialized WebApplication webapp) throws IdentityException {   
              // Roles
              IdentityRoleName employeRoleName = new IdentityRoleName();
              employeRoleName.setName("employe");
              entityManager.persist(employeRoleName);
              
              // Object types
              IdentityObjectType USER = new IdentityObjectType();
              USER.setName("USER");
              entityManager.persist(USER);
              
              IdentityObjectType GROUP = new IdentityObjectType();
              GROUP.setName("GROUP");
              entityManager.persist(GROUP);
              
              // Credential types
              IdentityObjectCredentialType PASSWORD = new IdentityObjectCredentialType();
              PASSWORD.setName("PASSWORD");
              entityManager.persist(PASSWORD);
              
              // Object relationship types
              IdentityObjectRelationshipType jbossIdentityMembership = new IdentityObjectRelationshipType();
              jbossIdentityMembership.setName("JBOSS_IDENTITY_MEMBERSHIP");
              entityManager.persist(jbossIdentityMembership);
              
              IdentityObjectRelationshipType jbossIdentityRole = new IdentityObjectRelationshipType();
              jbossIdentityRole.setName("JBOSS_IDENTITY_ROLE");
              entityManager.persist(jbossIdentityRole);
              
              // Groups
              IdentityObject usine = new IdentityObject();
              usine.setName("usine");
              usine.setType(GROUP);
              entityManager.persist(usine);
              
              // Users
              IdentityObject employe = new IdentityObject();
              employe.setName("employe");
              employe.setType(USER);
              entityManager.persist(employe);
              
              // Credentials
              IdentityObjectCredential employeCredential = new IdentityObjectCredential();
              employeCredential.setIdentityObject(employe);
              employeCredential.setType(PASSWORD);
              employeCredential.setValue("employe");
              entityManager.persist(employeCredential);
              
              // Group membership
              IdentityObjectRelationship employeUsineGroupRelationship = new IdentityObjectRelationship();
              employeUsineGroupRelationship.setRelationshipType(jbossIdentityMembership);
              employeUsineGroupRelationship.setFrom(usine);
              employeUsineGroupRelationship.setTo(employe);
              entityManager.persist(employeUsineGroupRelationship);
          }



      Once logged, if I ask the relationship manager to give me all the groups for the current user :



      RelationshipManager manager = identitySession.getRelationshipManager();
      Collection<Group> groups = manager.findAssociatedGroups(identity.getUser());
              
      System.out.println("Groups returned from RelationshipManager.findAssociatedGroups : ");
      if(groups.size() == 0) {
          System.out.println("none");
          return;
      }
      for(Group g:groups) {
          System.out.println("in "+g.getName());
      }



      It tells me that the user is in group 'usine'.


      But, if I ask the same question to the api, but instead passing by the identity object :



      System.out.println("Groups returned from identity.getGroups");
      Collection<Group> groups = identity.getGroups();
      if(groups.size() == 0)
          System.out.println("none");
      for(Group g:groups) {
          System.out.println("in "+g.getName());
      }



      It tells me that the current user is in no group.


      Also, identity.inGroup('usine', 'GROUP') always return false :(


      Is there a problem with how I populate the database or is it a known issue (tried to find but with no luck) ?

        • 1. Re: SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)
          shane.bryzak

          It was a bug in IdmAuthenticator, but has already been fixed.

          • 2. Re: SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)
            baraber

            I tried to build the latest SNAPSHOT (api and impl) from the develop branch.  It now tells me at runtime that I have an unsatisfied dependency on my Identity injection point. 


            Could you direct me a little ?  Is there an issue filed in jira for this problem ?

            • 3. Re: SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)
              shane.bryzak

              Could you please post a stacktrace?  There's no JIRA, I fixed the issue because I noticed it in the code.

              • 4. Re: SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)
                baraber

                Oh, I was going to produce it in order to post it, but I noticed that the exception was about the JpaPermissionStore, for wich I had commented the configuration in seam-beans.xml.   I uncommented the configuration and then had to put jboss logger in my pom for a classnotfounderror.


                Now my application boot and the login page is shown correctly.  But I get the following error on identity.login :




                ERROR: Login failed
                java.lang.RuntimeException: java.lang.IllegalArgumentException: name cannot be null
                     at org.jboss.seam.security.IdentityImpl.authenticate(IdentityImpl.java:245)
                     at org.jboss.seam.security.IdentityImpl.login(IdentityImpl.java:164)
                     at org.jboss.seam.security.org$jboss$weld$bean-WEB-INF$lib$seam-security-impl-3$1$0-20110806$041629-5-ManagedBean-class_org$jboss$seam$security$IdentityImpl_$$_WeldClientProxy.login(org$jboss$weld$bean-WEB-INF$lib$seam-security-impl-3$1$0-20110806$041629-5-ManagedBean-class_org$jboss$seam$security$IdentityImpl_$$_WeldClientProxy.java)
                     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                     at java.lang.reflect.Method.invoke(Method.java:597)
                     at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
                     at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
                     at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:43)
                     at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:56)
                     at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
                     at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
                     at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
                     at javax.faces.component.UICommand.broadcast(UICommand.java:315)
                     at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
                     at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
                     at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
                     at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
                     at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
                     at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
                     at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534)
                     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
                     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
                     at org.jboss.seam.servlet.exception.CatchExceptionFilter.doFilter(CatchExceptionFilter.java:62)
                     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
                     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
                     at org.jboss.seam.servlet.event.ServletEventBridgeFilter.doFilter(ServletEventBridgeFilter.java:72)
                     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
                     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
                     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
                     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
                     at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
                     at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
                     at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
                     at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
                     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
                     at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326)
                     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227)
                     at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170)
                     at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)
                     at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)
                     at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)
                     at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
                     at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
                     at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
                     at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
                     at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
                     at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
                     at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
                     at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
                     at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
                     at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
                     at java.lang.Thread.run(Thread.java:662)
                Caused by: java.lang.IllegalArgumentException: name cannot be null
                     at org.picketlink.idm.impl.api.model.SimpleRoleType.<init>(SimpleRoleType.java:41)
                     at org.picketlink.idm.impl.api.session.managers.RoleManagerImpl.findUserRoleTypes(RoleManagerImpl.java:580)
                     at org.picketlink.idm.impl.api.session.managers.RoleManagerImpl.findUserRoleTypes(RoleManagerImpl.java:552)
                     at org.jboss.seam.security.management.IdmAuthenticator.authenticate(IdmAuthenticator.java:48)
                     at org.jboss.seam.security.management.org$jboss$weld$bean-WEB-INF$lib$seam-security-impl-3$1$0-20110806$041629-5-ManagedBean-class_org$jboss$seam$security$management$IdmAuthenticator_$$_WeldClientProxy.authenticate(org$jboss$weld$bean-WEB-INF$lib$seam-security-impl-3$1$0-20110806$041629-5-ManagedBean-class_org$jboss$seam$security$management$IdmAuthenticator_$$_WeldClientProxy.java)
                     at org.jboss.seam.security.IdentityImpl.authenticate(IdentityImpl.java:225)
                     ... 53 more



                (Note that I'm not sure how org.jboss.seam.security.management.IdmAuthenticator.authenticate(IdmAuthenticator.java:48) can throw any exception :
                if (success))



                I already saw that name cannot be null somewhere when playing with relationships so, by curiosity, I tried to name the user-group relationship :


                employeUsineGroupRelationship.setName("TestName");


                I did authenticate correctly with that. 
                Then I come to my initial problem, but this time none of the Identity.getGroups and RelationshipManager.findAssociatedGroups returns any result.


                I'm being out of idea on this one.  What is the name of a user-group relationship for ?  Hope you can help ...

                • 5. Re: SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)
                  baraber

                  bump ...

                  • 6. Re: SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)
                    lightguard

                    I've asked Shane to take a look at this, but we're in meetings all this week, so it may not be until later when he replies.

                    • 7. Re: SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)
                      shane.bryzak

                      The role name table stores the possible names of user roles, from what I can tell you seem to be on the right track here (employe is a role type).


                      The exception suggests to me that you have an empty name entry in your IdentityRoleName table, however your code for populating this table seems to be correct:




                      IdentityRoleName employeRoleName = new IdentityRoleName();
                      employeRoleName.setName("employe");
                      entityManager.persist(employeRoleName);



                      Here's a couple of suggestions on what to try:



                      1. Visually inspect the contents of the table after deployment, to confirm the employe role type has been created

                      2. Try debugging JpaIdentityStore.getRelationshipNames() to see if the names are being correctly loaded from your IdentityRoleName entity.



                      • 8. Re: SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)
                        baraber

                        Thank you guys, your help is invaluable :)


                        Shane, I took a look at the IdentityRoleName table and it seems fine :



                        mysql> select * from IdentityRoleName;
                        +----+---------+
                        | id | name    |
                        +----+---------+
                        |  1 | employe |
                        +----+---------+
                        1 row in set (0.01 sec)



                        However, in the code I posted, I try to make a group membership (without role) :


                         // Group membership
                         IdentityObjectRelationship employeUsineGroupRelationship = new IdentityObjectRelationship();
                         employeUsineGroupRelationship.setRelationshipType(jbossIdentityMembership);
                         employeUsineGroupRelationship.setFrom(usine);
                         employeUsineGroupRelationship.setTo(employe);
                         entityManager.persist(employeUsineGroupRelationship);



                        Is it really possible/wanted to assign a user to a group without specifying any role name ?  If so, am I doing correctly ?


                        • 9. Re: SEAM-SECURITY identity.getGroups VS RelationshipManager.getAssociatedGroups(User)
                          baraber

                          Oh, I'm sorry, I realised that I had a problem with my local maven repo and our nexus proxy here so that I was not using the 3.1.0-SNAPSHOT that I had built myself.


                          But, trying to build and then use seam-security-3.1.0-SNAPSHOT caused me problems.
                          I checked out de develop branch and built the seam-security project (clean install).  This installed version 3.1.0-SNAPSHOT.  Then, in my other project, in the pom, I declare seam-surity like this :


                          <properties>
                              <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                              <seam.version>3.1.0.Beta2</seam.version>
                          </properties>
                          ...
                          <dependencyManagement>
                              <dependencies>
                                  <dependency>
                                      <groupId>org.jboss.seam</groupId>
                                      <artifactId>seam-bom</artifactId>
                                      <version>${seam.version}</version>
                                      <type>pom</type>
                                      <scope>import</scope>
                                  </dependency>
                              </dependencies>
                          </dependencyManagement>
                          ...
                          <dependency>
                              <groupId>org.jboss.seam.security</groupId>
                              <artifactId>seam-security</artifactId>
                              <version>3.1.0-SNAPSHOT</version>
                          </dependency>



                          Then, looking at the dependency tree of the project, I see that seam-security-3.1.0-SNAPSHOT is pointing on seam-security-api-3.1.0-Beta2.  This is causing errors since security-impl-3.1.0-SNAPSHOT uses classes of the api that weren't there in 3.1.0-Beta2.


                          I had to work around it by adding manually seam-security-api.  I don't know if the problem was on my side, since I found nothing wrong with the seam-security project, but preferred to mention it.


                          With all that done, I can confirm that finally it works on the latest snapshot.  Thank you, Shane and Jason :P