001: /*
002: * JOSSO: Java Open Single Sign-On
003: *
004: * Copyright 2004-2008, Atricore, Inc.
005: *
006: * This is free software; you can redistribute it and/or modify it
007: * under the terms of the GNU Lesser General Public License as
008: * published by the Free Software Foundation; either version 2.1 of
009: * the License, or (at your option) any later version.
010: *
011: * This software is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this software; if not, write to the Free
018: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
019: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
020: */
021:
022: package org.josso.jb42.agent;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.josso.gateway.identity.SSORole;
027: import org.josso.gateway.identity.SSOUser;
028: import org.josso.gateway.identity.service.BaseRoleImpl;
029: import org.josso.gateway.identity.service.BaseUserImpl;
030: import org.josso.tc55.agent.jaas.SSOGatewayLoginModule;
031:
032: import javax.security.auth.Subject;
033: import javax.security.auth.callback.CallbackHandler;
034: import javax.security.auth.login.LoginException;
035: import java.security.Principal;
036: import java.security.acl.Group;
037: import java.util.Iterator;
038: import java.util.Map;
039: import java.util.Set;
040:
041: /**
042: * SSOGatewayLogin Module for JBoss.
043: * <p>
044: * It specialized the SSOGatewayLoginModule by associating an additional
045: * group called ("Roles") which contains user roles.
046: * The original SSOGatewayLoginModule associates the user and its roles directly
047: * as Subject's Principals. This won't work in JBoss since it obtains user roles
048: * from a special Group that must be called "Roles".
049: * This LoginModule adds this special group, adds the roles as members of it and
050: * associates such group to the Subject as built by the SSOGatewayLoginModule.
051: * <p>
052: * To configure this JAAS Login Module module, add to the
053: * $JBOSS_HOME/server/default/conf/login-config.xml file the following entry :
054: * <p>
055: <pre>
056: <policy>
057: <!-- Used by JOSSO Agents for authenticating users against the Gateway -->
058: <application-policy name = "josso">
059: <authentication>
060: <login-module code = "org.josso.jb32.agent.JBossSSOGatewayLoginModule"
061: flag = "required">
062: <module-option name="debug">true</module-option>
063: </login-module>
064: </authentication>
065: </application-policy>
066: ...
067: </policy>
068: </pre>
069: *
070: * @author <a href="mailto:gbrigand@josso.org">Gianluca Brigandi</a>
071: * @version CVS $Id: JBossSSOGatewayLoginModule.java 338 2006-02-09 16:53:07Z sgonzalez $
072: */
073:
074: public class JBossSSOGatewayLoginModule extends SSOGatewayLoginModule {
075:
076: private static final Log logger = LogFactory
077: .getLog(JBossSSOGatewayLoginModule.class);
078:
079: private Subject _savedSubject;
080:
081: /** the principal to use when user is not authenticated **/
082: protected SSOUser _unauthenticatedIdentity;
083:
084: /**
085: * Initialize this LoginModule .
086: * Save the received Subject to change it when commit() gets invoked.
087: *
088: * @param subject the Subject to be authenticated.
089: *
090: * @param callbackHandler a CallbackHandler for communicating
091: * with the end user (prompting for user names and
092: * passwords, for example).
093: *
094: * @param sharedState shared LoginModule state.
095: *
096: * @param options options specified in the login Configuration
097: * for this particular LoginModule.
098: */
099: public void initialize(Subject subject,
100: CallbackHandler callbackHandler, Map sharedState,
101: Map options) {
102:
103: _savedSubject = subject;
104: super
105: .initialize(subject, callbackHandler, sharedState,
106: options);
107: // Check for unauthenticatedIdentity option.
108: String name = (String) options.get("unauthenticatedIdentity");
109: if (name != null) {
110: try {
111: _unauthenticatedIdentity = createIdentity(name);
112: logger.debug("Saw unauthenticatedIdentity=" + name);
113: } catch (Exception e) {
114: logger
115: .warn(
116: "Failed to create custom unauthenticatedIdentity",
117: e);
118: }
119: }
120: }
121:
122: /**
123: * This method supports the unauthenticatedIdentity property used by JBoss.
124: */
125: public boolean login() throws LoginException {
126:
127: if (!super .login()) {
128: // We have an unauthenticated user, use configured Principal
129: if (_unauthenticatedIdentity != null) {
130: logger
131: .debug("Authenticated as unauthenticatedIdentity : "
132: + _unauthenticatedIdentity);
133: _ssoUserPrincipal = _unauthenticatedIdentity;
134: _succeeded = true;
135: return true;
136: }
137: }
138:
139: return true;
140: }
141:
142: /*
143: * This method is called if the LoginContext's overall authentication succeeded.
144: *
145: * The Subject saved in the previously executed initialize() method, is modified
146: * by adding a new special Group called "Roles" whose members are the SSO user roles.
147: * JBoss will fetch user roles by examining such group.
148: *
149: * @exception LoginException if the commit fails.
150: *
151: * @return true if this LoginModule's own login and commit
152: * attempts succeeded, or false otherwise.
153: */
154: public boolean commit() throws LoginException {
155: boolean rc = false;
156: // HashMap setsMap = new HashMap();
157:
158: rc = super .commit();
159:
160: Set ssoRolePrincipals = _savedSubject
161: .getPrincipals(SSORole.class);
162: Group targetGrp = new BaseRoleImpl("Roles");
163: Iterator i = ssoRolePrincipals.iterator();
164: while (i.hasNext()) {
165: Principal p = (Principal) i.next();
166:
167: targetGrp.addMember(p); // Add user role to "Roles" group
168: }
169: // Add the "Roles" group to the Subject so that JBoss can fetch user roles.
170: _savedSubject.getPrincipals().add(targetGrp);
171:
172: Set ssoUserPrincipals = _savedSubject
173: .getPrincipals(SSOUser.class);
174: Group callerPrincipal = new BaseRoleImpl("CallerPrincipal");
175: Iterator j = ssoUserPrincipals.iterator();
176: if (j.hasNext()) {
177: Principal user = (Principal) j.next();
178: callerPrincipal.addMember(user);
179: }
180:
181: // Add the "CallerPrincipal" group to the Subject so that JBoss can fetch user.
182: _savedSubject.getPrincipals().add(callerPrincipal);
183:
184: return rc;
185: }
186:
187: protected SSOUser createIdentity(String username) {
188: return new BaseUserImpl(username);
189: }
190:
191: protected SSORole[] getRoleSets() throws LoginException {
192: if (_ssoUserPrincipal == _unauthenticatedIdentity) {
193: // Using unauthenticatedIdentity ..
194: if (logger.isDebugEnabled())
195: logger.debug("Using unauthenticatedIdentity "
196: + _ssoUserPrincipal + ", returning no roles.");
197:
198: return new SSORole[0];
199: }
200: return super.getRoleSets();
201: }
202:
203: }
|