/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at opensso/legal/CDDLv1.0.txt. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * $Id: WebServiceAuthenticatorImpl.java,v 1.4 2008/08/06 17:29:25 exu Exp $ * * Portions Copyrighted 2015-2016 ForgeRock AS. */ package com.sun.identity.liberty.ws.soapbinding; import static org.forgerock.openam.utils.Time.*; import java.security.AccessController; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.security.auth.Subject; import javax.servlet.http.HttpServletRequest; import org.forgerock.guice.core.InjectorHolder; import com.iplanet.am.util.Cache; import com.iplanet.dpro.session.service.InternalSession; import com.iplanet.dpro.session.service.SessionService; import com.iplanet.security.x509.CertUtils; import com.iplanet.sso.SSOToken; import com.iplanet.sso.SSOTokenManager; import com.sun.identity.security.AdminTokenAction; import com.sun.identity.shared.DateUtils; import com.sun.identity.shared.configuration.SystemPropertiesManager; import com.sun.identity.shared.datastruct.CollectionHelper; import com.sun.identity.shared.debug.Debug; import com.sun.identity.sm.ServiceSchema; import com.sun.identity.sm.ServiceSchemaManager; class WebServiceAuthenticatorImpl implements WebServiceAuthenticator { private static final String PRINCIPAL_PROP = "Principal"; private static final String PRINCIPALS_PROP = "Principals"; private static final String AUTH_TYPE_PROP = "AuthType"; private static final String AUTH_INSTANT_PROP = "authInstant"; private static final String ANONYMOUS_PRINCIPAL = "anonymous"; private static final String SESSION_SERVICE_NAME = "iPlanetAMSessionService"; private static final String MAX_SESSION_TIME = "iplanet-am-session-max-session-time"; private static final String IDLE_TIME = "iplanet-am-session-max-idle-time"; private static final String CACHE_TIME = "iplanet-am-session-max-caching-time"; private static final int DEFAULT_MAX_SESSION_TIME = 120; private static final int DEFAULT_IDLE_TIME = 30; private static final int DEFAULT_CACHE_TIME = 3; private static Cache ssoTokenCache = new Cache(1000); private static SSOTokenManager ssoTokenManager = null; private static ServiceSchema sessionSchema = null; private static String rootSuffix = SystemPropertiesManager.get("com.iplanet.am.rootsuffix"); private static Debug debug = Debug.getInstance("libIDWSF"); static { try { ssoTokenManager = SSOTokenManager.getInstance(); } catch (Exception ex) { debug.error("WebServiceAuthenticatorImpl.static: " + "unable to get SSOTokenManager", ex); } try { SSOToken adminToken = (SSOToken) AccessController.doPrivileged( AdminTokenAction.getInstance()); ServiceSchemaManager scm = new ServiceSchemaManager( SESSION_SERVICE_NAME, adminToken); sessionSchema = scm.getDynamicSchema(); } catch (Exception ex) { debug.error("WebServiceAuthenticatorImpl.static: " + "unable to get session schema", ex); } } /** * Authenticates a web service using its certificates. * * @param message a Message object that needs authentication. * @param request the HttpServletRequest object that comes from the web * service * @return a SSOToken Object for the valid certificates after * successful authentication or null if authentication fails. */ public Object authenticate(Message message,Subject subject,Map state, HttpServletRequest request) { List certs = null; X509Certificate clientCert = message.getPeerCertificate(); if (clientCert != null) { // SSL client auth certificate certs = new ArrayList(2); certs.add(clientCert); } X509Certificate messageCert = message.getMessageCertificate(); if (messageCert != null) { if (certs == null) { certs = new ArrayList(1); } certs.add(messageCert); } String principal = null; StringBuffer principalsSB = null; if (certs == null) { principal = ANONYMOUS_PRINCIPAL; } else { Set principalsSet = new HashSet(6); for(Iterator iter = certs.iterator(); iter.hasNext();) { X509Certificate cert = (X509Certificate)iter.next(); if (debug.messageEnabled()) { debug.message( "WebServiceAuthenticatorImpl.authenticate: cert = " + cert); } String subjectDN = CertUtils.getSubjectName(cert); if (principal == null) { principal = subjectDN; } else if (!principal.equals(subjectDN)) { principalsSet.add(subjectDN); } String issuerDN = CertUtils.getIssuerName(cert); principalsSet.add(issuerDN); } principalsSB = new StringBuffer(50); for(Iterator iter = principalsSet.iterator(); iter.hasNext();) { String str = (String)iter.next(); if (principalsSB.length() == 0) { principalsSB.append(str); } else { principalsSB.append("|").append(str); } } } if (debug.messageEnabled()) { debug.message("WebServiceAuthenticatorImpl.authenticate"+ ": principal = " + principal + ", principals = " + principalsSB); } String authMech = message.getAuthenticationMechanism(); String cacheKey = authMech + " " + principal; if (debug.messageEnabled()) { debug.message("WebServiceAuthenticatorImpl.authenticate"+ ": cacheKey = " + cacheKey); } SSOToken ssoToken = null; ssoToken = (SSOToken)ssoTokenCache.get(cacheKey); if (ssoToken != null) { if (ssoTokenManager.isValidToken(ssoToken)) { if (debug.messageEnabled()) { debug.message("WebServiceAuthenticatorImpl." + "authenticate: found ssoToken in cache"); } return ssoToken; } if (debug.messageEnabled()) { debug.message("WebServiceAuthenticatorImpl." + "authenticate: ssoToken in cache expired"); } synchronized (ssoTokenCache) { ssoTokenCache.remove(cacheKey); } ssoToken = null; } String authInstant = null; try { InternalSession is = InjectorHolder.getInstance(SessionService.class).newInternalSession(null, false); is.activate(""); Map attrs = sessionSchema.getAttributeDefaults(); is.setMaxSessionTime(CollectionHelper.getIntMapAttr( attrs, MAX_SESSION_TIME, DEFAULT_MAX_SESSION_TIME, debug)); is.setMaxIdleTime(CollectionHelper.getIntMapAttr( attrs, IDLE_TIME, DEFAULT_IDLE_TIME, debug)); is.setMaxCachingTime(CollectionHelper.getIntMapAttr( attrs, CACHE_TIME, DEFAULT_CACHE_TIME, debug)); is.putProperty(AUTH_TYPE_PROP, message.getAuthenticationMechanism()); authInstant = DateUtils.toUTCDateFormat(newDate()); is.putProperty(AUTH_INSTANT_PROP, authInstant); ssoToken = SSOTokenManager.getInstance() .createSSOToken(is.getID().toString()); } catch (Exception ex) { debug.error("WebServiceAuthenticatorImpl.authenticate: " + "Unable to get SSOToken", ex); } if (ssoToken == null) { return null; } try { ssoToken.setProperty(PRINCIPAL_PROP, principal); if (principalsSB != null) { ssoToken.setProperty(PRINCIPALS_PROP, principalsSB.toString()); } if(authInstant != null) { ssoToken.setProperty(AUTH_INSTANT_PROP, authInstant); } ssoToken.setProperty(AUTH_TYPE_PROP, message.getAuthenticationMechanism()); SSOTokenManager.getInstance().refreshSession(ssoToken); ssoTokenCache.put(cacheKey, ssoToken); } catch (Exception ex) { debug.error("WebServiceAuthenticatorImpl.authenticate: " + "Unable to set SSOToken property", ex); return null; } return ssoToken; } }