/** * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2007 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: RPSigninResponse.java,v 1.8 2009/12/14 23:42:48 mallas Exp $ * */ package com.sun.identity.wsfederation.servlet; import com.sun.identity.plugin.session.SessionException; import com.sun.identity.plugin.session.SessionManager; import com.sun.identity.plugin.session.SessionProvider; import com.sun.identity.saml2.common.SAML2Constants; import com.sun.identity.saml2.profile.SPACSUtils; import com.sun.identity.shared.debug.Debug; import com.sun.identity.wsfederation.common.WSFederationConstants; import com.sun.identity.wsfederation.common.WSFederationException; import com.sun.identity.wsfederation.common.WSFederationUtils; import com.sun.identity.wsfederation.jaxb.entityconfig.SPSSOConfigElement; import com.sun.identity.wsfederation.logging.LogUtil; import com.sun.identity.wsfederation.meta.WSFederationMetaManager; import com.sun.identity.wsfederation.meta.WSFederationMetaUtils; import com.sun.identity.wsfederation.plugins.SPAccountMapper; import com.sun.identity.wsfederation.plugins.SPAttributeMapper; import com.sun.identity.wsfederation.profile.RequestSecurityTokenResponse; import com.sun.identity.wsfederation.profile.RequestedSecurityToken; import com.sun.identity.wsfederation.profile.SPCache; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * This class handles the sign-in response from the identity provider */ public class RPSigninResponse extends WSFederationAction { private static Debug debug = WSFederationUtils.debug; private String wresult; private String wctx; /** Creates a new instance of RPSigninResponse * @param request HTTP Servlet request * @param response HTTP Servlet response * @param wresult wresult parameter from request * @param wctx wctx parameter from request */ public RPSigninResponse(HttpServletRequest request, HttpServletResponse response, String wresult, String wctx) { super(request,response); this.wresult = wresult; this.wctx = wctx; } /** * Processes the sign-in response, redirecting the browser wreply URL * supplied in the sign-in request via the HttpServletResponse passed to * the constructor. */ public void process() throws WSFederationException, IOException { String classMethod = "RPSigninResponse.process: "; if ((wresult == null) || (wresult.length() == 0)) { String[] data = {request.getQueryString()}; LogUtil.error(Level.INFO, LogUtil.MISSING_WRESULT, data, null); throw new WSFederationException(WSFederationUtils.bundle. getString("nullWresult")); } RequestSecurityTokenResponse rstr = null; try { rstr = RequestSecurityTokenResponse.parseXML(wresult); } catch (WSFederationException wsfe) { String[] data = {wresult}; LogUtil.error(Level.INFO, LogUtil.INVALID_WRESULT, data, null); throw new WSFederationException(WSFederationUtils.bundle. getString("invalidWresult")); } if ( debug.messageEnabled() ) { debug.message(classMethod +"Received RSTR: " + rstr.toString()); } String realm = null; String requestURL = request.getRequestURL().toString(); // get entity id and orgName String metaAlias = WSFederationMetaUtils.getMetaAliasByUri(requestURL); realm = WSFederationMetaUtils.getRealmByMetaAlias(metaAlias); WSFederationMetaManager metaManager = WSFederationUtils.getMetaManager(); String spEntityId = null; try { spEntityId = metaManager.getEntityByMetaAlias(metaAlias); } catch (WSFederationException wsfe) { String[] data = {wsfe.getLocalizedMessage(), metaAlias, realm}; LogUtil.error(Level.INFO, LogUtil.CONFIG_ERROR_GET_ENTITY_CONFIG, data, null); String[] args = {metaAlias, realm}; throw new WSFederationException(WSFederationConstants.BUNDLE_NAME, "invalidMetaAlias", args); } if (realm == null || realm.length() == 0) { realm = "/"; } SPSSOConfigElement spssoconfig = metaManager.getSPSSOConfig(realm, spEntityId); int timeskew = SAML2Constants.ASSERTION_TIME_SKEW_DEFAULT; String timeskewStr = WSFederationMetaUtils.getAttribute(spssoconfig, SAML2Constants.ASSERTION_TIME_SKEW); if (timeskewStr != null && timeskewStr.trim().length() > 0) { timeskew = Integer.parseInt(timeskewStr); if (timeskew < 0) { timeskew = SAML2Constants.ASSERTION_TIME_SKEW_DEFAULT; } } if (debug.messageEnabled()) { debug.message(classMethod + "timeskew = " + timeskew); } // check Assertion and get back a Map of relevant data including, // Subject, SOAPEntry for the partner and the List of Assertions. if ( debug.messageEnabled() ) { debug.message(classMethod +" - verifying assertion"); } // verifyToken will throw an exception, rather than return null, so we // need not test the return value Map smap = rstr.getRequestedSecurityToken().verifyToken(realm, spEntityId, timeskew); assert smap != null; Map attributes = WSFederationMetaUtils.getAttributes(spssoconfig); SPAccountMapper acctMapper = getSPAccountMapper(attributes); SPAttributeMapper attrMapper = getSPAttributeMapper(attributes); String userName = acctMapper.getIdentity(rstr, spEntityId, realm); if ( userName == null ) { throw new WSFederationException(WSFederationUtils.bundle. getString("nullUserID")); } String idpEntityId = metaManager.getEntityByTokenIssuerName( realm, rstr.getRequestedSecurityToken().getIssuer()); List attrs = rstr.getRequestedSecurityToken().getAttributes(); Map attrMap = null; if (attrs != null) { attrMap = attrMapper.getAttributes(attrs, userName, spEntityId, idpEntityId, realm); } String authLevel = smap.get(SAML2Constants.AUTH_LEVEL).toString(); // Set up Attributes for session creation Map sessionInfoMap = new HashMap(); sessionInfoMap.put(SessionProvider.REALM, realm); sessionInfoMap.put(SessionProvider.PRINCIPAL_NAME, userName); sessionInfoMap.put(SessionProvider.AUTH_LEVEL, authLevel); Object session = null; try { SessionProvider sessionProvider = SessionManager.getProvider(); session = sessionProvider.createSession(sessionInfoMap, request, response, null); SPACSUtils.setAttrMapInSession(sessionProvider, attrMap, session); String[] idpArray = {idpEntityId}; sessionProvider.setProperty(session, WSFederationConstants.SESSION_IDP, idpArray); RequestedSecurityToken rst = rstr.getRequestedSecurityToken(); if(isAssertionCacheEnabled(spssoconfig)) { String tokenID = rst.getTokenId(); String[] assertionID = {tokenID}; sessionProvider.setProperty(session, "AssertionID", assertionID); SPCache.assertionByIDCache.put(tokenID, rst.toString()); } } catch (SessionException se) { String[] data = {se.getLocalizedMessage(),realm, userName, authLevel}; LogUtil.error(Level.INFO, LogUtil.CANT_CREATE_SESSION, data, null); throw new WSFederationException(se); } String target = null; if (wctx != null) { target = WSFederationUtils.removeReplyURL(wctx); } else { target = WSFederationMetaUtils.getAttribute(spssoconfig, SAML2Constants.DEFAULT_RELAY_STATE); } String[] data = {wctx, LogUtil.isErrorLoggable(Level.FINER)? wresult : rstr.getRequestedSecurityToken().getTokenId(), realm, userName, authLevel, target}; LogUtil.access(Level.INFO, LogUtil.SSO_SUCCESSFUL, data, session); if ( target == null ) { // What to do? There was no wreply URL specified, and there is no // default target configured PrintWriter pw = response.getWriter(); pw.println("Logged in"); return; } response.sendRedirect(target); } private static SPAccountMapper getSPAccountMapper( Map attributes) throws WSFederationException { SPAccountMapper acctMapper = null; List acctMapperList = (List)attributes.get( SAML2Constants.SP_ACCOUNT_MAPPER); if (acctMapperList != null) { try { acctMapper = (SPAccountMapper) (Class.forName((String)acctMapperList.get(0)). newInstance()); if (debug.messageEnabled()) { debug.message( "RPSigninResponse.getSPAccountMapper: mapper = " + (String)acctMapperList.get(0)); } } catch (ClassNotFoundException cfe) { throw new WSFederationException(cfe); } catch (InstantiationException ie) { throw new WSFederationException(ie); } catch (IllegalAccessException iae) { throw new WSFederationException(iae); } } if (acctMapper == null) { throw new WSFederationException( WSFederationUtils.bundle.getString("failedAcctMapper")); } return acctMapper; } private SPAttributeMapper getSPAttributeMapper(Map attributes) throws WSFederationException { SPAttributeMapper attrMapper = null; List attrMapperList = (List)attributes.get( SAML2Constants.SP_ATTRIBUTE_MAPPER); if (attrMapperList != null) { try { attrMapper = (SPAttributeMapper) (Class.forName((String)attrMapperList.get(0)). newInstance()); } catch (ClassNotFoundException cfe) { throw new WSFederationException(cfe); } catch (InstantiationException ie) { throw new WSFederationException(ie); } catch (IllegalAccessException iae) { throw new WSFederationException(iae); } } if (attrMapper == null) { throw new WSFederationException( WSFederationUtils.bundle.getString("failedAttrMapper")); } return attrMapper; } /** Sets the attribute map in the session * * @param sessionProvider Session provider * @param attrMap the Attribute Map * @param session the valid session object * @throws com.sun.identity.plugin.session.SessionException */ public static void setAttrMapInSession( SessionProvider sessionProvider, Map attrMap, Object session) throws SessionException { if (attrMap != null && !attrMap.isEmpty()) { Set entrySet = attrMap.entrySet(); for(Iterator iter = entrySet.iterator(); iter.hasNext();) { Map.Entry entry = (Map.Entry)iter.next(); String attrName = (String)entry.getKey(); Set attrValues = (Set)entry.getValue(); if(attrValues != null && !attrValues.isEmpty()) { sessionProvider.setProperty( session, attrName, (String[]) attrValues.toArray( new String[attrValues.size()])); if (WSFederationUtils.debug.messageEnabled()) { WSFederationUtils.debug.message( "SPACSUtils.setAttrMapInSession: AttrMap:" + attrName + " , " + attrValues); } } } } } private boolean isAssertionCacheEnabled(SPSSOConfigElement spssoconfig) { String enabled = WSFederationMetaUtils.getAttribute(spssoconfig, SAML2Constants.ASSERTION_CACHE_ENABLED); if(enabled == null) { //TODO: until the console/cli is fixed for this attribute, // return true. return true; } return "true".equalsIgnoreCase(enabled) ? true : false; } }