3 Replies Latest reply on Mar 24, 2009 4:12 AM by Perry Rhodan

    sessioncontext getPrincipal returns empty string in 5.0.1GA

    Janne Maijanen Newbie

      Hello!

      I'm using JBoss application serer version 5.0.1 GA.

      After first succesfull login on a user using custom login module, the SessionContext.getPrincipal method returns an empty string.

      Subsecuent calls with same user account return the user name correctly when calling getPrincipal.

      anyone have a clue why it is working as described?

      Br, Janne

        • 1. Re: sessioncontext getPrincipal returns empty string in 5.0.
          Perry Rhodan Newbie

          How do you login ? From an remote-client, web-app or anything else ? How looks your login code...?

          • 2. Re: sessioncontext getPrincipal returns empty string in 5.0.
            Janne Maijanen Newbie

            Hello!

            I'm using a remote java client and here's the client side test code;

            Hashtable<String,String> jndiProps=new Hashtable<String, String>();
            jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            jndiProps.put(Context.PROVIDER_URL, "jnp://localhost:1099");
            jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
            
            InitialContext initialContext;
            try {
             SecurityClient securityClient = SecurityClientFactory.getSecurityClient();
             securityClient.setSimple("jamai", "jamai1");
             securityClient.login();
             initialContext = new InitialContext(jndiProps);
            
             Object obj=initialContext.lookup("test/SecTestBean/remote");
             SecTest ops=(SecTest)PortableRemoteObject.narrow(obj, SecTest.class);
             String currentUser=ops.getCurrentUser("jamai");
             System.out.println(currentUser);
            } catch (Exception e) {
             e.printStackTrace();
            }
            


            And then here's a basic login module used just for testing this case, it does not perform the actual authentication;

            package test.ejb;
            
            import java.security.Principal;
            import java.security.acl.Group;
            import java.util.Map;
            
            import javax.security.auth.Subject;
            import javax.security.auth.callback.Callback;
            import javax.security.auth.callback.CallbackHandler;
            import javax.security.auth.callback.NameCallback;
            import javax.security.auth.callback.PasswordCallback;
            import javax.security.auth.login.LoginException;
            
            import org.jboss.security.SimpleGroup;
            import org.jboss.security.SimplePrincipal;
            import org.jboss.security.auth.spi.AbstractServerLoginModule;
            
            public class BypassLogin extends AbstractServerLoginModule{
             private boolean debug;
             private Principal identity;
             private SimpleGroup userRoles;
             private SimpleGroup callerPrincipal;
             private String userName;
            
             @Override
             protected Principal getIdentity() {
             return identity;
             }
            
             @Override
             protected Group[] getRoleSets() throws LoginException {
             return new Group[] { userRoles, callerPrincipal };
             }
            
             /////////////////////////////
            
             public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
             super.initialize(subject,callbackHandler, sharedState, options);
             this.userRoles = new SimpleGroup( "Roles" );
             this.callerPrincipal=new SimpleGroup("CallerPrincipal");
             }
            
             /**
             * Handle the login. Remember to set the loginOk boolean when successful
             * @return true if login was successful
             */
             public boolean login() throws LoginException {
             String username = null;
             String password = null;
            
             if( identity == null ) {
             if( callbackHandler == null ) {
             throw new LoginException( "No callback handler for login");
             }
            
             NameCallback nc = new NameCallback("Name:", "guest");
             PasswordCallback pc = new PasswordCallback("Password:", false);
             Callback[] callbacks = {nc, pc};
            
             try {
             callbackHandler.handle(callbacks);
             username = nc.getName();
             if(username==null) throw new LoginException("User name is null.");
             char[] tmpPassword = pc.getPassword();
             if( tmpPassword != null ) {
             password = new String(tmpPassword);
             }
             }
             catch(LoginException e) {
             if(debug)System.out.println(e.getMessage());
             throw e;
             }
             catch ( Exception e ) {
             if(debug)e.printStackTrace();
             throw new LoginException( "Error in login; "+e.getMessage());
             }
            
             this.userName=username;
             }
            
             loginOk = true;
             return true;
             }
            
             private void authorize(String userName) throws LoginException {
             try {
             identity = createIdentity(userName);
             } catch (Exception e) {
             throw new LoginException("Error creating identity; "+e.getMessage());
             }
            
             callerPrincipal.addMember(new SimplePrincipal(userName));
             userRoles.addMember(new SimplePrincipal("delos"));
             }
            
             @Override
             public boolean commit() throws LoginException {
             authorize(userName);
             return true;
             }
            }
            


            And then the simple server side bean;

            package test.ejb;
            
            import java.security.Principal;
            
            import javax.annotation.Resource;
            import javax.ejb.Remote;
            import javax.ejb.SessionContext;
            import javax.ejb.Stateless;
            
            @Stateless
            @org.jboss.ejb3.annotation.SecurityDomain(value="bypass")
            @Remote(SecTest.class)
            public class SecTestBean implements SecTest {
             @Resource
             private SessionContext ctx;
            
             public String getCurrentUser(String thoughtUserName) throws Exception {
             Principal principal=ctx.getCallerPrincipal();
             if(!thoughtUserName.equals(principal.getName())) throw new Exception("MISMATCHING CTX.PRINCIPAL USER; "+thoughtUserName+"!="+principal.getName());
             return principal.getName();
             }
            }
            


            So i checked the situation at server side, and the principal is "" when the client first time is run, and also the credientals returned by SecurityAssociation are also null.

            Maybe I have missed something in the login module development, because after succesfull login the principal and credientals exist correctly.

            Br, Janne

            • 3. Re: sessioncontext getPrincipal returns empty string in 5.0.
              Perry Rhodan Newbie

              Could you try to set:

              securityClient.setVmwideAssociation(true)