/*
* JOSSO: Java Open Single Sign-On
*
* Copyright 2004-2009, Atricore, Inc.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
package org.josso.jb32.agent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.josso.gateway.identity.SSORole;
import org.josso.gateway.identity.SSOUser;
import org.josso.gateway.identity.service.BaseRoleImpl;
import org.josso.gateway.identity.service.BaseUserImpl;
import org.josso.tc50.agent.jaas.SSOGatewayLoginModule;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* SSOGatewayLogin Module for JBoss.
* <p>
* It specialized the SSOGatewayLoginModule by associating an additional
* group called ("Roles") which contains user roles.
* The original SSOGatewayLoginModule associates the user and its roles directly
* as Subject's Principals. This won't work in JBoss since it obtains user roles
* from a special Group that must be called "Roles".
* This LoginModule adds this special group, adds the roles as members of it and
* associates such group to the Subject as built by the SSOGatewayLoginModule.
* <p>
* To configure this JAAS Login Module module, add to the
* $JBOSS_HOME/server/default/conf/login-config.xml file the following entry :
* <p>
<pre>
<policy>
<!-- Used by JOSSO Agents for authenticating users against the Gateway -->
<application-policy name = "josso">
<authentication>
<login-module code = "org.josso.jb32.agent.JBossSSOGatewayLoginModule"
flag = "required">
<module-option name="debug">true</module-option>
<module-option name="unauthenticatedIdentity">guest</module-option>
</login-module>
</authentication>
</application-policy>
...
</policy>
</pre>
*
* @author <a href="mailto:gbrigand@josso.org">Gianluca Brigandi</a>
* @version CVS $Id: JBossSSOGatewayLoginModule.java 974 2009-01-14 00:39:45Z sgonzalez $
*/
public class JBossSSOGatewayLoginModule extends SSOGatewayLoginModule {
private static final Log logger = LogFactory.getLog(JBossSSOGatewayLoginModule .class);
private Subject _savedSubject;
/** the principal to use when user is not authenticated **/
protected SSOUser _unauthenticatedIdentity;
/**
* Initialize this LoginModule .
* Save the received Subject to change it when commit() gets invoked.
*
* @param subject the Subject to be authenticated.
*
* @param callbackHandler a CallbackHandler for communicating
* with the end user (prompting for user names and
* passwords, for example).
*
* @param sharedState shared LoginModule state.
*
* @param options options specified in the login Configuration
* for this particular LoginModule.
*/
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map sharedState, Map options) {
_savedSubject = subject;
super.initialize(subject, callbackHandler, sharedState, options);
// Check for unauthenticatedIdentity option.
String name = (String) options.get("unauthenticatedIdentity");
if( name != null )
{
try
{
_unauthenticatedIdentity = createIdentity(name);
logger.debug("Saw unauthenticatedIdentity="+name);
}
catch(Exception e)
{
logger.warn("Failed to create custom unauthenticatedIdentity", e);
}
}
}
/**
* This method supports the unauthenticatedIdentity property used by JBoss.
*/
public boolean login() throws LoginException {
if (!super.login()) {
// We have an unauthenticated user, use configured Principal
if (_unauthenticatedIdentity != null) {
logger.debug("Authenticated as unauthenticatedIdentity : " + _unauthenticatedIdentity);
_ssoUserPrincipal = _unauthenticatedIdentity;
_succeeded = true;
return true;
}
return false;
}
return true;
}
/*
* This method is called if the LoginContext's overall authentication succeeded.
*
* The Subject saved in the previously executed initialize() method, is modified
* by adding a new special Group called "Roles" whose members are the SSO user roles.
* JBoss will fetch user roles by examining such group.
*
* @exception LoginException if the commit fails.
*
* @return true if this LoginModule's own login and commit
* attempts succeeded, or false otherwise.
*/
public boolean commit() throws LoginException {
boolean rc = false;
// HashMap setsMap = new HashMap();
rc = super.commit();
Set ssoRolePrincipals = _savedSubject.getPrincipals(SSORole.class);
Group targetGrp = new BaseRoleImpl("Roles");
Iterator i = ssoRolePrincipals.iterator();
while (i.hasNext()) {
Principal p = (Principal)i.next();
targetGrp.addMember(p); // Add user role to "Roles" group
}
// Add the "Roles" group to the Subject so that JBoss can fetch user roles.
_savedSubject.getPrincipals().add(targetGrp);
return rc;
}
protected SSOUser createIdentity(String username) {
return new BaseUserImpl(username);
}
protected SSORole[] getRoleSets() throws LoginException {
if (_ssoUserPrincipal == _unauthenticatedIdentity) {
// Using unauthenticatedIdentity ..
if(logger.isDebugEnabled())
logger.debug("Using unauthenticatedIdentity " + _ssoUserPrincipal + ", returning no roles.");
return new SSORole[0];
}
return super.getRoleSets();
}
}