users@glassfish.java.net

Re: Non-default security realm and ProgrammaticLogin in Glassfish?

From: <glassfish_at_javadesktop.org>
Date: Mon, 12 Nov 2007 11:02:20 PST

In GlassFish v1 and GlassFish v2, it is possible to use a non-default security realm from a Java SE client.

On the server side, I think it should be defined the "permit" realm in "$GLASSFISH_HOME/domains/domain/config/login.conf" (restart required). For example, supposing it is an JDBC realm:

permit {
 com.sun.enterprise.security.auth.login.JDBCLoginModule required;
};

In "sun-ejb-jar.xml" descriptor, I used to specify "transport-config" for session beans (it may not be required, but I had problems with another X.509 certificate realm):

<ejb>
  <ejb-name>PermitServiceBean</ejb-name>
  <jndi-name>ejb/permit/stateless/PermitServiceBean</jndi-name>
  <ior-security-config>
        <transport-config>
          <integrity>NONE</integrity>
          <confidentiality>NONE</confidentiality>
          <establish-trust-in-target>NONE</establish-trust-in-target>
          <establish-trust-in-client>NONE</establish-trust-in-client>
        </transport-config>
        <as-context>
          <auth-method>username_password</auth-method>
          <realm>permit</realm>
          <required>true</required>
        </as-context>
        <sas-context>
          <caller-propagation>NONE</caller-propagation>
        </sas-context>
  </ior-security-config>
</ejb>


I also used to package secured EJB3 Session Beans in "ear" archive with the realm name in the "sun-application.xml" descriptor (i cannot say if it is really required):

<sun-application>
  <security-role-mapping>
    <role-name>user</role-name>
    <group-name>clerks</group-name>
  </security-role-mapping>
  <security-role-mapping>
    <role-name>power</role-name>
    <group-name>manager</group-name>
  </security-role-mapping>
  <realm>permit</realm>
</sun-application>



On the client side,
instead of "ProgramaticLogin.login", I used another method "com.sun.enterprise.security.auth.LoginContextDriver.doClientLogin(com.sun.enterprise.appclient.AppContainer.USERNAME_PASSWORD, new UserPasswordCallbackHandler ("testuser","testpassword"));". The code for "UserPasswordCallbackHandler" class is at the end of the message. Note: It was not required to inform the "permit" realm name (it was auto-detected on runtime).

But I also had to execute the Java SE application with some special parameters:
$JAVA_HOME/bin/java -Xmx128m -Djava.security.auth.login.config=auth.conf -Djava.naming.rmi.security.manager=yes -Dorg.omg.CORBA.ORBInitialHost=127.0.0.1 -Dorg.omg.CORBA.ORBInitialPort=3700 -Djava.security.policy=client.policy -cp $MYAPP_HOME/myClient.jar:$MYAPP_HOME/myEjb3Interfaces.jar:$GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar myAppClassName

And create the "auth.conf" file to define the client login module for the "permit" realm (on the client side):
permit {
        com.sun.enterprise.security.auth.login.ClientPasswordLoginModule required debug=false;
};


This is the code for "UserPasswordCallbackHandler" class code was (maybe there exist a similar class in "javaee.jar" or "appserv-rt.jar", but I didn't found it):

import java.io.IOException;

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.callback.UnsupportedCallbackException;

public class UserPasswordCallbackHandler implements CallbackHandler
{

    // attributes
    private String user;
    private char[] password;


    // constructors
    public UserPasswordCallbackHandler() { }

    public UserPasswordCallbackHandler(String user, char password[])
    {
        this.user = user;
        this.password = password;
    }

    public UserPasswordCallbackHandler(String user, String password)
    {
        this.user = user;
        this.password = password.toCharArray();
    }


    // methods
    public void setUser(String user)
    {
        this.user = user;
    }

    public void setPassword(char password[])
    {
        this.password = password;
    }

    public void setPassword(String password)
    {
        this.password = password.toCharArray();
    }


    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
    {
        for(int i = 0; i < callbacks.length; i++)
        {
            if (callbacks[i] instanceof NameCallback)
            {
                NameCallback nc = (NameCallback) callbacks[i];
                nc.setName(user);
            }
            else if(callbacks[i] instanceof PasswordCallback)
            {
                PasswordCallback pc = (PasswordCallback) callbacks[i];
                pc.setPassword(password);
            }
            else
            {
                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
            }
        }
    }
}



I hope it also works for you.
[Message sent by forum member 'jmarine' (jmarine)]

http://forums.java.net/jive/thread.jspa?messageID=245086