6 Replies Latest reply on Nov 9, 2009 2:32 AM by David Lee

    IdentityManager.grantRole needs a relogin to see effect?

    Miguel Cohnen Newbie

      Hi,


      I have a seam app configured with jpaIdentityManager and drools for managing permissions. When a user creates a 'Place', I craete a new role that is associated to that 'Place', and grant the user with that role. This is my code:




      @Override
           public String persist(){
                String res = super.persist();
                if ("persisted".equals(res)){ 
                     new RunAsOperation() {         
                          public void execute() {
                               identityManager.createRole(getRole());
                               identityManager.grantRole(currentUser.getUsername(), getRole());
                          }         
                     }.addRole("admin").run();     
                }
                return res;
           }



      The problem is that later drools tries to get if this user has the new role and it is failing. If I launch Identity.instance.hasRole(ROLENAME) it returns false, but checking the database and calling identityManager.listGrantedRoles() shows me that the role has been successfully inserted.
      What is worst, if I logout and login again, the role is there and everything works as expected. What am I missing?


      Thank you!

        • 1. Re: IdentityManager.grantRole needs a relogin to see effect?
          Marco Röösli Newbie

          I had the same problem. I refresh the identity roles after granting new roles.
          But I am not sure if this is the correct way. It works but maybe is there a better way to update the roles.



          @SuppressWarnings("unchecked")
             public void refreshIdentityRoles(Identity identity) {
                List<Principal> toRemoveList = new ArrayList<Principal>();
                // remove all roles
                Subject subject = identity.getSubject();
          
                for (Group sg : subject.getPrincipals(Group.class)) {
                   if (Identity.ROLES_GROUP.equals(sg.getName())) {
                      Enumeration<Principal> e = (Enumeration<Principal>) sg.members();
                      while (e.hasMoreElements()) {
                         Principal member = (Principal) e.nextElement();
                         toRemoveList.add(member);
                      }
                      for (Principal member : toRemoveList) {
                         sg.removeMember(member);
                      }
                   }
                }
          
                // add all roles from database for the identity object
                for (String roleName : listImpliedRolesForUser(identity.getPrincipal().getName())) {
                   if (!identity.hasRole(roleName)) {
                      identity.addRole(roleName);
                   }
                }
             }




          • 2. Re: IdentityManager.grantRole needs a relogin to see effect?
            Miguel Cohnen Newbie

            Hi,
            thank you for your answer, but it is still not working for me. I can see how it calls


            identity.addRole(roleName);



            with all the roles, even the recently added one. But then it seems that drools is not aware of that change... If I debug I can see that Identity.instance.hasRole(NEWROLE) returns true, but it looks as if drools has not updated it's context...


            Any help? I'm stuck with this... :(


            Thank you!

            • 3. Re: IdentityManager.grantRole needs a relogin to see effect?
              Miguel Cohnen Newbie

              Damn! I found this post


              DroolsSecurityProblemRemovingRoleFromWorkingMemory


              If I remove the runasOperation and refresh the roles as you said... it works! What is wrong with runasoperation and drools?


              Any ideas?


              Thank you!




              • 4. Re: IdentityManager.grantRole needs a relogin to see effect?
                Shane Bryzak Master

                RuleBasedPermissionResolver.synchronizeContext() should populate the working memory with the current Principal and roles from Identity, and removes any roles for which Identity.hasRole() returns false.  This happens on every single permission check, so if the role isn't present in Identity.subject then it won't be in the working memory.  If you're using RunAsOperation then only the roles contained in the operation will be used (the principal and subject in Identity are temporarily replaced with these).

                • 5. Re: IdentityManager.grantRole needs a relogin to see effect?
                  David Lee Newbie

                  I think I have a similar issue.  However, even when I remove RunAsOperation, I can't add the role to the user.


                  I'm using IdentityManager to create users and manage my roles.  However, when I do s:hasRole or identity.hasRole it can't find the role.  What's weirder is, if I do identity.addRole(admin); in my authenticator.authenticate method, it won't add the admin role.


                  My database has the proper mappings from User to Role, but the identity component doesn't seem to pick it up.  When I do a RunAsOperation admin, and check for my roles with my email, I do get the proper role of admin.  However, if I check my roles right outside of the RunAsOperation, none exists.


                  I removed the RunAsOperation block in my authentication method, but the same problem still occurs.


                  This issue has been killing me.  Please help!







                       public boolean authenticate() {
                            log.info("authenticating {0}", credentials.getUsername());
                  
                            String email = credentials.getUsername();
                            String password = credentials.getPassword();
                  
                  
                            if(identity.hasRole("ADMIN")) {
                                 facesMessages.add("IDENTITY " + email + " HAS ADMIN ROLE!!");
                            } else {
                                 facesMessages.add("IDENTITY " + email + " DOESN'T HAVE ADMIN ROLE...");
                                 identity.addRole("ADMIN");
                                 
                                 if(identity.hasRole("ADMIN")) {
                                      facesMessages.add("IDENTITY " + email + " HAS ADMIN ROLE!!");
                                 } else {
                                      facesMessages.add("IDENTITY " + email + " STILL DOESN'T HAVE ADMIN ROLE...");
                                 }
                            }
                            
                            if (identityManager.authenticate(email, password)) {
                                 UserHome userHome = new UserHome();
                                 
                                 // Set currentUserId for UserHome
                                 currentUserId = (Long) entityManager.createQuery(
                                           "select u.id from User u where u.email=?1")
                                           .setParameter(1,email).getSingleResult();
                                 userHome.setCurrentUserId(currentUserId);
                  /*
                                 new RunAsOperation() {
                                      @Override
                                      public void execute() {
                                           // TODO: Add role
                                           String uname = identity.getCredentials().getUsername();
                                           
                                           if(identity.addRole("ADMIN")) {
                                                facesMessages.add("IDENTITY " + uname + " ADDROLE SUCCESS");
                                           } else {
                                                
                                                facesMessages.add("IDENTITY " + uname + " ADDROLE FAIL");
                                                if(identity.hasRole("ADMIN")) {
                                                     facesMessages.add("IDENTITY " + uname + " ALREADY HAS ROLE");
                                                } else {
                                                     facesMessages.add("IDENTITY " + uname + " NO ROLE");
                                                }
                                           }
                                           
                                           // Create user with identity manager
                                           if(identityManager.grantRole(credentials.getUsername(), "ADMIN")) {
                                                facesMessages.add("IDENTITYMANAGER " + credentials.getUsername() + " GRANTROLE SUCCESS");
                                           } else {
                                                facesMessages.add("IDENTITYMANAGER " + credentials.getUsername() + " GRANTROLE FAIL");
                                                for (String role : identityManager.getGrantedRoles(credentials.getUsername())) {
                                                     facesMessages.add("has role = " + role);
                                                }
                                           }
                                           for (String role : identityManager.getImpliedRoles(credentials.getUsername())) {
                                                facesMessages.add("has implied role = " + role);
                                           }
                                           for (String role : identityManager.listRoles()) {
                                                facesMessages.add("all roles = " + role);
                                           }
                                      }
                                 }.addRole("ADMIN").run();
                                 */
                                 if(identity.hasRole("ADMIN")) {
                                      facesMessages.add("IDENTITY " + email + " HAS ADMIN ROLE!!");
                                 } else {
                                      facesMessages.add("IDENTITY " + email + " DOESN'T HAVE ADMIN ROLE...");
                                      identity.addRole("ADMIN");
                                      
                                      if(identity.hasRole("ADMIN")) {
                                           facesMessages.add("IDENTITY " + email + " HAS ADMIN ROLE!!");
                                      } else {
                                           facesMessages.add("IDENTITY " + email + " STILL DOESN'T HAVE ADMIN ROLE...");
                                      }
                                 }
                                 return true;
                            }
                  
                            return false;
                       }





                  Result:
                  IDENTITY . DOESN'T HAVE ADMIN ROLE...
                  IDENTITY . STILL DOESN'T HAVE ADMIN ROLE...
                  IDENTITY . DOESN'T HAVE ADMIN ROLE...
                  IDENTITY . STILL DOESN'T HAVE ADMIN ROLE...


                  identity has the proper roles in the runasoperation block though.

                  • 6. Re: IdentityManager.grantRole needs a relogin to see effect?
                    David Lee Newbie

                    Nevermind.  I went out for a couple hours and came back and it was working.  Must've been a glitch.