12 Replies Latest reply: Oct 24, 2011 6:59 AM by henk de boer RSS

Custom Principal class problem. SessionContext always return

Marcin Misiewicz Newbie

Hi

I need to store in the principal class not only name of the principal but also id from database. So I have created my own login module which inherits from the jboss DatabaseServerLoginModule. In the method getUsersPassword I also get the id of the user from the db. Here is the code snipet :

 password = rs.getString(1);
 password = convertRawPassword(password);
 if (trace)
 log.trace("Obtained user password");
 Long id = rs.getLong(2);
 if (getIdentity() instanceof SmartOfficePrincipal) {
 log.info("Setting id to the principal");
 ((SmartOfficePrincipal)getIdentity()).setId(id);
 }


In login-config.xml I have configured login module to use my own principal implementation.
login-config.xml :
 <application-policy name="smartoffice">
 <authentication>
 <login-module code="org.jboss.security.ClientLoginModule" flag="required">
 <module-option name="restore-login-identity">true</module-option>
 </login-module>
 <login-module code="com.foo.SmartOfficeDatabaseLoginModule" flag="required">
 <module-option name="principalClass">com.foo.SmartOfficePrincipal</module-option>
 <module-option name="dsJndiName">java:/smartofficeDS</module-option>
 <module-option name="principalsQuery">SELECT PASSWORD,ID FROM SMR_USERS_ASSIGN WHERE LOGIN=?</module-option>
 <module-option name="rolesQuery">SELECT ROLES.ROLE, 'Roles' FROM SMR_USER_ROLES AS ROLES,
 SMR_USERS_ASSIGN AS USERS WHERE USERS.LOGIN = ? AND ROLES.
USER_ID = USERS.ID</module-option>
 <module-option name="hashAlgorithm">MD5</module-option>
 <module-option name="unauthenticatedIdentity">anonymous</module-option>
 </login-module>
 </authentication>
 </application-policy>


My principal class :
public class SmartOfficePrincipal extends SimplePrincipal implements Serializable {

 private static final long serialVersionUID = 2079488098348121376L;

 private Long id;

 public SmartOfficePrincipal(String name) {
 super(name);
 }

 public void setId(Long id) {
 this.id = id;
 }

 public Long getId() {
 return id;
 }

 @Override
 public int hashCode() {
 final int prime = 31;
 int result = super.hashCode();
 result = prime * result + ((id == null) ? 0 : id.hashCode());
 return result;
 }

 @Override
 public boolean equals(Object obj) {
 if (this == obj)
 return true;
 if (!super.equals(obj))
 return false;
 if (getClass() != obj.getClass())
 return false;
 SmartOfficePrincipal other = (SmartOfficePrincipal) obj;
 if (id == null) {
 if (other.id != null)
 return false;
 } else if (!id.equals(other.id))
 return false;
 return true;
 }
}


Everything works fine I can login to the application but when I try to get the callerPrincipal from the SessionContext object I get SimplePrincipal instance.
I can't cast to SmartOfficePrincipal.

Also when I try to get principal in the entitylistener using the following statement :
 Principal principal = SecurityAssociation.getPrincipal();


I get the instance of SimplePrincipal class. I need user id because in entity listener i would like to set the user who have last modify object or created.
So I don't have to remember to set up this by hand in the code.

Also in my aspects I prefer to use the user id.

What am I doing wrong ?


Thanks a lot.

Martin

  • 1. Re: Custom Principal class problem. SessionContext always re
    Marcin Misiewicz Newbie

    I guess it is a bug in JBoss.

    When I call

    SecurityAssociation.getSubject().getPrincipals()
    

    I get the set of the principals where the first element in this set is the my own implementation of the principal class and that's right, subject gets filled with principals in the LoginModule commit method.

    However when I call Sec
    SecurityAssociation.getPrincipal();
    or
    SecurityAssociation.getCallerPrincipal();
    or
    sessionContext.getCallerPrincipal();
    

    I always get the instance of the SimplePrincipal.

    It seems that my loginModule works well, but during the propagation of the caller principal jboss is ignoring my principal class and sets his default.

    Martin

  • 2. Re: Custom Principal class problem. SessionContext always re
    Alexander Lengson Newbie

    Hello everybody,

     

    I have the same situation.

    I've written custom login module MyLoginModule on top of org.jboss.security.auth.spi.UsernamePasswordLoginModule

    My login module creates instance of the custom implementation MyPrincipal of java.security.Principal

     

    Although I always get instance of SimplePrincipal when try to obtain the caller of the EJB from within this EJB:

     

    @Resource

    protected SessionContext sctx;

    ...
    sctx.getCallerPrincipal();  // returns SimplePrincipal instead of MyPrincipal

     

     

    But call to

    SecurityAssociation.getSubject().getPrincipals();

    returns set which contains correct instance of MyPrinciple

    The following entry appears in the logs then:

    WARN  [org.jboss.security.SecurityAssociation] (WorkerThread#0[10.119.0.140:49777]) You are using deprecated api to getSubject. Use security context based approach

     

    Could somebody confirm this is an unresolved bug actually please?

    JBoss 5.1.0GA

     

    Thanks,

    Alexander.

     

    P.S.

    There is an article about writing custom principles at http://community.jboss.org/wiki/UsingCustomPrincpalsWith

    It describes how to compose custom principle, but does not have exaple of retrieving it, probably that would be useful addition.

  • 3. Re: Custom Principal class problem. SessionContext always re
    Marcin Misiewicz Newbie

    Hi

     

    I have created class ServerUtils with the folllowing static which properly returns principal :

     

     

    import org.jboss.security.SecurityAssociation;
    import org.jboss.security.auth.spi.Util;
     
    public class ServerUtils {
     
         public static SmartOfficePrincipal getPrincipal() {
              if (SecurityAssociation.getSubject().getPrincipals(SmartOfficePrincipal.class).toArray().length == 0) 
                   return null;
              return (SmartOfficePrincipal) SecurityAssociation.getSubject().getPrincipals(SmartOfficePrincipal.class).toArray()[0];
         }
     
    ...
    }
    
    

     

     

    And it works perfectly

  • 4. Re: Custom Principal class problem. SessionContext always re
    Alexander Lengson Newbie

    Hi, Marcin.

     

    That's right. Static method of SecurityAssociation does return proper principal.

    The trouble described here is the wrong principal being returned by the method of auto injected SessionContext.

     

    Alexander.

  • 5. Re: Custom Principal class problem. SessionContext always re
    M Arnold Newbie

    I have also hit this bug (JBoss 5.1 GA).  Annoying - I will have to write JBoss specific code to workaround.

     

    Can anybody confirm that it is a recognised bug?  Will it be fixed?

  • 6. Re: Custom Principal class problem. SessionContext always return
    Anil Saldhana Master

    As of JBoss5.x, SecurityAssociation is deprecated.

     

    SecurityContext API is preferred.   SecurityContextAssociation.getSecurityContext()

     

    securityContext.getUtil().getUserPrincipal()

  • 7. Re: Custom Principal class problem. SessionContext always return
    Alexander Lengson Newbie

    ANIL SALDHANA

    Thank you for that notification. That's just great, but this is still not J2EE compliant code.

    Are you aware of the plans for fixing the following notation?

    @Resource

    protected SessionContext sctx;

    ...
    sctx.getCallerPrincipal();  // returns SimplePrincipal instead of MyPrincipal
  • 8. Re: Custom Principal class problem. SessionContext always return
    Anil Saldhana Master

    Custom Principal is never part of any Java EE specs.

     

    Here is a bug report for investigation and potential fix:

    https://jira.jboss.org/browse/JBAS-8427

  • 9. Re: Custom Principal class problem. SessionContext always return
    Marcus Moyses Novice

    To get the custom principal returned you will need to update EJB3 jars as there is a known issue (https://jira.jboss.org/browse/EJBTHREE-1756) and also have your identity (the custom principal) added to a group named CallerPrincipal in the Subject. See http://community.jboss.org/wiki/UsingCustomPrincpalsWith for an example login module (more specifically the getRoleSets method).

  • 10. Re: Custom Principal class problem. SessionContext always re
    sirwayne Newbie

    I have the same problem in JBoss 6.0.0 final. I get alwas the SimplePrincipal

     

    Interceptor

     

     

    @Interceptor
    public class MyInterceptor
    
    @Resource    
    private SessionContext sessionContext;    
    
    @AroundInvoke     
    public Object injectMap(InvocationContext ic) throws Exception {   
    
         System.out.println(sessionContext.getCallerPrincipal());   Always SimplePrincipal      
         System.out.println(SecurityContextAssociation.getSecurityContext().getUtil().getCredential());    
         System.out.println(SecurityContextAssociation.getSecurityContext().getUtil().getUserPrincipal());   
         MyPrincipal ppPrincipal = (MyPrincipal) SecurityContextAssociation.getSecurityContext().getUtil().
         getSubject().getPrincipals(MyPrincipal.class); 
    

     

    TesLogin

     

     

    public class TestLogin extends AbstractServerLoginModule { 
    
    protected MyPrincipal principal;
    protected String sessionId; 
    
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
         super.initialize(subject, callbackHandler, sharedState, options); 
         sessionId = UUID.randomUUID().toString(); 
         try { 
              principal = (MyPrincipal) createIdentity(getUsername()); 
         } catch (Exception e) 
         { // TODO Auto-generated catch block e.printStackTrace(); }
    }
    @Override 
    protected Principal createIdentity(String name) throws Exception { 
         return new MyPrincipal(sessionId, name); 
    } 
    
    @Override 
    protected Principal getIdentity()
    { 
         return principal; 
    }
    
     @Override 
    protected Group[] getRoleSets() throws LoginException { 
         SimpleGroup rolesGroup = new SimpleGroup(&quot;Roles&quot;); 
         rolesGroup.addMember(getIdentity()); 
         Group[] roleSets = {rolesGroup}; return roleSets; 
    }  
    
    protected String getUsername() throws LoginException   { 
         return "admin";
    }
    

     

     

    public class MyPrincipal implements Principal{
    
    private String sessionId; 
    private String name; 
    
    public PPPrincipal(String sessionId, String name) 
    { 
    this.sessionId = sessionId; 
    this.name = name; 
    } 
    
    @Override public String getName()
     { return name; } 
    
    public String getSessionId() { 
         return sessionId; 
    } 
    } 
    
    
    

     

     

    What's wrong?

  • 11. Re: Custom Principal class problem. SessionContext always return
    superDev superDev Newbie

    I have exactly the same problem with Micheal, JBoss 6.0.0 final. always get the SimplePrincipal instead of my Cumtom Principal, has anyone successfully get Cumtom Principal from SessionContext under JBoss 6.0.0 final ?

  • 12. Re: Custom Principal class problem. SessionContext always return
    henk de boer Master

    superDev superDev wrote:

     

    I have exactly the same problem with Micheal, JBoss 6.0.0 final. always get the SimplePrincipal instead of my Cumtom Principal, has anyone successfully get Cumtom Principal from SessionContext under JBoss 6.0.0 final ?

     

    It seems this is simply impossible. It's a LONG standing bug in JBoss AS and there doesn't seem to be any hope of this ever getting fixed.

     

    Meanwhile, it seems the suggestion offered here is a workaround: http://community.jboss.org/message/141598#141598

     

    Via the PolicyContext you can get the original Subject that the login module (parent) creates, and from that you can get your Custom Principal. I'm going to try this method. If anyone knows of any bad side-effects with using this method, please let me know.