I am testing the propagation of JAAS Subject with a custom Principal from a standalone EJB client running on a raw Java runtime to a JavaEE server. I am targeting both JBoss
probably this will help you with the price to use proprietary websphere-classes. as I remember , websphere does NOT propagate the jaas caller-subject, this is typical to ibm
package foo.bar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.login.CredentialExpiredException;
import org.apache.log4j.Logger;
import com.ibm.websphere.security.WSSecurityException;
import com.ibm.websphere.security.auth.CredentialDestroyedException;
import com.ibm.websphere.security.auth.WSSubject;
import com.ibm.websphere.security.cred.WSCredential;
public class IdentityHelper
{
private static final Logger log = Logger.getLogger(IdentityHelper.class);
private static final String CLASS_OBJECT = "java.util.HashMap";
private static final String KEY_OBJECT = "java.lang.String";
private static final String VALUE_OBJECT = "java.util.HashSet";
private Subject subject=null;
private WSCredential creds;
private Set publicCredentials=null;
public IdentityHelper(Subject _subject) throws WSSecurityException
{
if(_subject==null)
{
IdentityHelper.log.warn("given subject was null, using Caller-Subject or the RunAs-Subject!");
this.subject = WSSubject.getCallerSubject();
if(this.subject==null)this.subject=WSSubject.getRunAsSubject();
}
else
{
this.subject=_subject;
}
init();
}
public IdentityHelper() throws WSSecurityException
{
this.subject=WSSubject.getRunAsSubject();
if(this.subject==null)
{
IdentityHelper.log.warn("using Caller-Subject NOT the RunAs-Subject!");
this.subject = WSSubject.getCallerSubject();
}
init();
}
private void init() throws WSSecurityException
{
Set credSet= this.subject.getPublicCredentials(WSCredential.class);
//set should contain exactly one WSCredential
if(credSet.size() > 1) throw new WSSecurityException("Expected one WSCredential, found " + credSet.size());
if(credSet.isEmpty())
{
throw new WSSecurityException("Found no credentials");
}
Iterator iter= credSet.iterator();
this.creds=(WSCredential) iter.next();
this.publicCredentials=this.subject.getPublicCredentials();
}
public WSCredential getWSCredential() throws WSSecurityException
{
return this.creds;
}
public List getGroups() throws WSSecurityException,CredentialDestroyedException,CredentialExpiredException
{
WSCredential c = this.getWSCredential();
return c.getGroupIds();
}
/**
* helper method for obtaining user attributes from Subject objects.
* @param subject
* @return
*/
@SuppressWarnings("unchecked")
public Map> getAttributes()
{
Map> attributes = null;
Iterator> i = this.subject.getPublicCredentials().iterator();
while (attributes == null && i.hasNext())
{
Map> tmp = null;
Object o = i.next();
if(IdentityHelper.log.isDebugEnabled())
{
IdentityHelper.log.debug("checking for attributes (class name): " + o.getClass().getName());
}
if(!o.getClass().getName().equals(CLASS_OBJECT))
continue;//loop through
tmp = (Map) o;
Object tObject = null;
Iterator> t = null;
t = tmp.keySet().iterator();
tObject = t.next();
if(IdentityHelper.log.isDebugEnabled())
{
IdentityHelper.log.debug("checking for attributes (key object name): " + tObject.getClass().getName());
}
if(!tObject.getClass().getName().equals(KEY_OBJECT))
continue;//loop through
t = tmp.values().iterator();
tObject = t.next();
if(IdentityHelper.log.isDebugEnabled())
{
IdentityHelper.log.debug("checking for attributes (value object name): " + tObject.getClass().getName());
}
if(!tObject.getClass().getName().equals(VALUE_OBJECT))
continue;//loop through
attributes = (Map) o;
}
if (attributes == null)
{
attributes = new HashMap>();
}
return attributes;
}
public Subject getSubject()
{
return this.subject;
}
protected Set getPublicCredentials() {
return publicCredentials;
}
}
see also: Getting the caller subject from the thread for JAAS and Getting the RunAs subject from the thread