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: package org.josso.gateway;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.josso.Lookup;
026: import org.josso.SecurityDomain;
027: import org.josso.auth.Authenticator;
028: import org.josso.auth.Credential;
029: import org.josso.auth.SimplePrincipal;
030: import org.josso.auth.exceptions.AuthenticationFailureException;
031: import org.josso.auth.exceptions.SSOAuthenticationException;
032: import org.josso.gateway.event.security.SSOSecurityEventManager;
033: import org.josso.gateway.identity.SSORole;
034: import org.josso.gateway.identity.SSOUser;
035: import org.josso.gateway.identity.exceptions.SSOIdentityException;
036: import org.josso.gateway.identity.service.SSOIdentityManager;
037: import org.josso.gateway.identity.service.SSOIdentityProvider;
038: import org.josso.gateway.session.SSOSession;
039: import org.josso.gateway.session.exceptions.NoSuchSessionException;
040: import org.josso.gateway.session.exceptions.SSOSessionException;
041: import org.josso.gateway.session.service.SSOSessionManager;
042: import org.josso.gateway.assertion.AuthenticationAssertion;
043: import org.josso.gateway.assertion.AuthenticationAssertionImpl;
044: import org.josso.gateway.assertion.AssertionManager;
045: import org.josso.gateway.assertion.service.AssertionIdGenerator;
046: import org.josso.gateway.assertion.service.AssertionIdGeneratorImpl;
047:
048: import javax.security.auth.Subject;
049: import java.security.Principal;
050: import java.util.Set;
051: import java.util.HashMap;
052: import java.util.Map;
053:
054: /**
055: * This is the default SSO Gateway implementation.
056: *
057: * @author <a href="mailto:sgonzalez@josso.org">Sebastian Gonzalez Oyuela</a>
058: * @version $Id: SSOGatewayImpl.java 508 2008-02-18 13:32:29Z sgonzalez $
059: */
060: public class SSOGatewayImpl implements SSOGateway {
061:
062: private static final Log logger = LogFactory
063: .getLog(SSOGatewayImpl.class);
064:
065: private boolean _initialized;
066:
067: public SSOGatewayImpl() {
068:
069: }
070:
071: /**
072: * This method logins a user into de SSO infrastructure.
073: *
074: * @param cred the user credentials used as user identity proof.
075: * @param scheme the authentication scheme name to be used for logging in the user.
076: *
077: * @throws SSOAuthenticationException if authentication fails.
078: * @throws SSOException if an error occurs.
079: */
080: public SSOSession login(Credential[] cred, String scheme,
081: SSOContext ctx) throws SSOException,
082: SSOAuthenticationException {
083:
084: try {
085: SSOIdentityProvider ip = Lookup.getInstance()
086: .lookupSSOIdentityProvider();
087:
088: return ip.login(cred, scheme, ctx);
089:
090: } catch (AuthenticationFailureException e) {
091: throw e;
092: } catch (SSOAuthenticationException e) {
093: throw e;
094: } catch (SSOIdentityException e) {
095: throw new SSOException(e.getMessage(), e);
096: } catch (SSOSessionException e) {
097: throw new SSOException(e.getMessage(), e);
098: } catch (Exception e) {
099: throw new SSOException(e.getMessage(), e);
100: }
101: }
102:
103: /**
104: * Create an authentication assertion based on the supplied credentials. If assertion is successful a new session
105: * is created for the subject which can be referenced through the corresponding assertion identifier.
106: *
107: * @param credentials
108: * @param scheme
109: * @param ctx
110: * @return
111: * @throws SSOException
112: * @throws SSOAuthenticationException
113: */
114: public AuthenticationAssertion assertIdentity(
115: Credential[] credentials, String scheme, SSOContext ctx)
116: throws SSOException, SSOAuthenticationException {
117:
118: try {
119: SSOIdentityProvider ip = Lookup.getInstance()
120: .lookupSSOIdentityProvider();
121: return ip.assertIdentity(credentials, scheme, ctx);
122: } catch (AuthenticationFailureException e) {
123: throw e;
124: } catch (SSOAuthenticationException e) {
125: throw e;
126: } catch (Exception e) {
127: throw new SSOException(e.getMessage(), e);
128: }
129:
130: }
131:
132: /**
133: * Create an authentication assertion from a previous existing and valid one.
134: *
135: * @param sessionId SSO session identifier for the session to be bound to the new assertion.
136: * @return
137: * @throws SSOException
138: */
139: public AuthenticationAssertion assertIdentity(String sessionId)
140: throws SSOException {
141:
142: try {
143: SSOIdentityProvider ip = Lookup.getInstance()
144: .lookupSSOIdentityProvider();
145: return ip.assertIdentity(sessionId);
146: } catch (Exception e) {
147: throw new SSOException(e.getMessage(), e);
148: }
149:
150: }
151:
152: /**
153: * Logouts a user from the SSO infrastructure.
154: *
155: * @param ctx the sso external context during method execution
156: * @throws SSOException
157: */
158: public void logout(SSOContext ctx) throws SSOException {
159:
160: try {
161:
162: SSOIdentityProvider ip = Lookup.getInstance()
163: .lookupSSOIdentityProvider();
164: ip.logout(ctx);
165: } catch (Exception e) {
166: logger.error(e.getMessage(), e);
167: throw new SSOException(e.getMessage(), e);
168: }
169: }
170:
171: public Credential newCredential(String schemeName, String name,
172: Object value) throws SSOAuthenticationException {
173: try {
174:
175: SecurityDomain domain = Lookup.getInstance()
176: .lookupSecurityDomain();
177: Authenticator au = domain.getAuthenticator();
178:
179: return au.newCredential(schemeName, name, value);
180: } catch (Exception e) {
181: logger.error(e.getMessage(), e);
182: return null;
183: }
184: }
185:
186: public String getPrincipalName(String schemeName, Credential[] creds)
187: throws SSOAuthenticationException {
188: try {
189:
190: SecurityDomain domain = Lookup.getInstance()
191: .lookupSecurityDomain();
192: Authenticator au = domain.getAuthenticator();
193:
194: Principal p = au.getPrincipal(schemeName, creds);
195: if (p != null)
196: return p.getName();
197:
198: } catch (Exception e) {
199: logger.error(e.getMessage(), e);
200:
201: }
202: return null;
203: }
204:
205: /**
206: * Finds a user associated to the given session.
207: *
208: * @param sessionId
209: *
210: * @throws SSOException
211: */
212: public SSOUser findUserInSession(String sessionId)
213: throws SSOException {
214: try {
215:
216: SecurityDomain domain = Lookup.getInstance()
217: .lookupSecurityDomain();
218: SSOIdentityManager im = domain.getIdentityManager();
219: return im.findUserInSession(sessionId);
220:
221: } catch (NoSuchSessionException e) {
222: // Session is not valid ... (we could signal it with a specific exception)
223: if (logger.isDebugEnabled())
224: logger.debug(e.getMessage(), e);
225:
226: throw new SSOException(e.getMessage(), e);
227:
228: } catch (SSOIdentityException e) {
229: if (logger.isDebugEnabled())
230: logger.debug(e.getMessage(), e);
231:
232: throw new SSOException(e.getMessage(), e);
233:
234: } catch (Exception e) {
235: logger.error(e.getMessage(), e);
236:
237: throw new SSOException(e.getMessage(), e);
238: }
239: }
240:
241: public SSORole[] findRolesByUsername(String username)
242: throws SSOException {
243: try {
244: SecurityDomain domain = Lookup.getInstance()
245: .lookupSecurityDomain();
246: SSOIdentityManager im = domain.getIdentityManager();
247: return im.findRolesByUsername(username);
248:
249: } catch (SSOIdentityException e) {
250: if (logger.isDebugEnabled())
251: logger.debug(e.getMessage(), e);
252:
253: throw new SSOException(e.getMessage(), e);
254: } catch (Exception e) {
255: logger.error(e.getMessage(), e);
256: throw new SSOException(e.getMessage(), e);
257: }
258: }
259:
260: public SSOSession findSession(String jossoSessionId)
261: throws SSOException, NoSuchSessionException {
262: try {
263: SecurityDomain domain = Lookup.getInstance()
264: .lookupSecurityDomain();
265: SSOSessionManager sm = domain.getSessionManager();
266: return sm.getSession(jossoSessionId);
267: } catch (NoSuchSessionException e) {
268: throw e;
269:
270: } catch (SSOIdentityException e) {
271: if (logger.isDebugEnabled())
272: logger.debug(e.getMessage(), e);
273:
274: throw new SSOException(e.getMessage(), e);
275: } catch (Exception e) {
276: logger.error(e.getMessage(), e);
277: throw new SSOException(e.getMessage(), e);
278: }
279: }
280:
281: protected void notifyLoginFailed(SSOContext ctx,
282: Credential[] credentials, String scheme, Throwable error) {
283: try {
284: // We expect a spetial Event Manager ...
285: SSOSecurityEventManager em = (SSOSecurityEventManager) Lookup
286: .getInstance().lookupSecurityDomain()
287: .getEventManager();
288: em.fireAuthenticationFailureEvent(ctx.getUserLocation(),
289: scheme, credentials, error);
290:
291: } catch (Exception e) {
292: logger.error("Can't notify login failure : "
293: + e.getMessage(), e);
294: }
295: }
296:
297: protected void notifyLoginSuccess(SSOContext ctx, String username,
298: SSOSession session, String scheme) {
299: try {
300: // We expect a spetial Event Manager ...
301: SSOSecurityEventManager em = (SSOSecurityEventManager) Lookup
302: .getInstance().lookupSecurityDomain()
303: .getEventManager();
304: em.fireAuthenticationSuccessEvent(ctx.getUserLocation(),
305: scheme, username, session.getId());
306:
307: } catch (Exception e) {
308: logger.error("Can't notify login success : "
309: + e.getMessage(), e);
310: }
311: }
312:
313: private void notifyLogoutFail(SSOContext ctx, Throwable error) {
314: try {
315: // We expect a spetial Event Manager ...
316: SSOSecurityEventManager em = (SSOSecurityEventManager) Lookup
317: .getInstance().lookupSecurityDomain()
318: .getEventManager();
319: em.fireLogoutFailureEvent(ctx.getUserLocation(), ctx
320: .getCurrentSession().getUsername(), ctx
321: .getCurrentSession().getId(), error);
322:
323: } catch (Exception e) {
324: logger.error("Can't notify login success : "
325: + e.getMessage(), e);
326: }
327: }
328:
329: protected void notifyLogoutSuccess(SSOContext ctx) {
330: try {
331: // We expect a spetial Event Manager ...
332: SSOSecurityEventManager em = (SSOSecurityEventManager) Lookup
333: .getInstance().lookupSecurityDomain()
334: .getEventManager();
335: em.fireLogoutSuccessEvent(ctx.getUserLocation(), ctx
336: .getCurrentSession().getUsername(), ctx
337: .getCurrentSession().getId());
338:
339: } catch (Exception e) {
340: logger.error("Can't notify login success : "
341: + e.getMessage(), e);
342: }
343:
344: }
345:
346: /**
347: * Initializes the SSO gateway.
348: */
349: public void initialize() {
350: _initialized = true;
351: }
352:
353: public boolean isInitialized() {
354: return _initialized;
355: }
356:
357: public void destroy() {
358: _initialized = false;
359: }
360:
361: }
|