0748565aad6a8878aecb88a26081c9bb10c00279Peter Major/*
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * The contents of this file are subject to the terms of the Common Development and
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * Distribution License (the License). You may not use this file except in compliance with the
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * License.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major *
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * specific language governing permission and limitations under the License.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major *
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * When distributing Covered Software, include this CDDL Header Notice in each file and include
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * Header, with the fields enclosed by brackets [] replaced by your own identifying
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * information: "Portions copyright [year] [name of copyright owner]".
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major *
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * Copyright 2016 ForgeRock AS.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major */
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorpackage com.sun.identity.wsfederation.servlet;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport static com.sun.identity.wsfederation.common.WSFederationConstants.*;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport static org.forgerock.openam.utils.Time.newDate;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport static org.forgerock.openam.wsfederation.common.ActiveRequestorException.newReceiverException;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport static org.forgerock.openam.wsfederation.common.ActiveRequestorException.newSenderException;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport java.io.ByteArrayOutputStream;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport java.io.IOException;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport java.io.InputStream;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport java.io.OutputStream;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport java.net.MalformedURLException;
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Majorimport java.nio.charset.StandardCharsets;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport java.text.ParseException;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport java.util.Collections;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport java.util.Date;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport java.util.List;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.servlet.ServletException;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.servlet.http.HttpServletRequest;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.servlet.http.HttpServletResponse;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.xml.soap.MessageFactory;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.xml.soap.MimeHeaders;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.xml.soap.SOAPBody;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.xml.soap.SOAPConstants;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.xml.soap.SOAPException;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.xml.soap.SOAPHeader;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport javax.xml.soap.SOAPMessage;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport org.forgerock.openam.saml2.plugins.WsFedAuthenticator;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport org.forgerock.openam.utils.IOUtils;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport org.forgerock.openam.utils.StringUtils;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport org.forgerock.openam.wsfederation.common.ActiveRequestorException;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport org.owasp.esapi.ESAPI;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport org.w3c.dom.Element;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport org.w3c.dom.Node;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport org.w3c.dom.NodeList;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.iplanet.sso.SSOToken;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.plugin.session.SessionException;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.plugin.session.SessionManager;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.saml.assertion.Assertion;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.saml.common.SAMLConstants;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.saml.common.SAMLUtils;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.saml2.common.SAML2Utils;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.saml2.common.SOAPCommunicator;
1d684f1accbc962da075532ff3b1ad66459dd750Peter Majorimport com.sun.identity.shared.Constants;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.shared.DateUtils;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.shared.debug.Debug;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.shared.whitelist.URLPatternMatcher;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.wsfederation.common.WSFederationException;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.wsfederation.common.WSFederationUtils;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.wsfederation.jaxb.entityconfig.IDPSSOConfigElement;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.wsfederation.meta.WSFederationMetaManager;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.wsfederation.meta.WSFederationMetaUtils;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorimport com.sun.identity.wsfederation.profile.SAML11RequestedSecurityToken;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major/**
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * A {@link WSFederationAction} implementation that processes WS-Federation Active Requestor Profile SOAP requests. It
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * does so, by processing RST/Issue requests based on the 2005/02 spec, to allow backwards compatibility with legacy
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * client applications.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major */
0748565aad6a8878aecb88a26081c9bb10c00279Peter Majorpublic class ActiveRequest extends WSFederationAction {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private static final Debug DEBUG = Debug.getInstance("libWSFederation");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major public static final String NO_PROOF_KEY_KEY_TYPE = "http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey";
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private static final String ACTION = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue";
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private static final String REQUEST_TYPE = "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue";
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private String realm = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private String messageId = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private String username = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private char[] password = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private String expires = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private String address = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major public ActiveRequest(HttpServletRequest request, HttpServletResponse response) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major super(request, response);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major /**
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * Processes the incoming SOAP request {@link #parseAndValidateRequest(SOAPMessage, IDPSSOConfigElement) parsing
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * and validating the request}, and then authenticating the end-user using a customizable {@link WsFedAuthenticator}
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * implementation. In case of a successful login, a SAML1.1 RequestedSecurityToken is returned in a SOAP message.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major *
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * @throws ServletException If there was a problem whilst rendering the response.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * @throws IOException If there was an IO error whilst working with the request or response.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major * @throws WSFederationException If there was an unrecoverable error while processing the request.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major */
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major @Override
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major public void process() throws ServletException, IOException, WSFederationException {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final String metaAlias = WSFederationMetaUtils.getMetaAliasByUri(request.getRequestURI());
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (StringUtils.isEmpty(metaAlias)) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DEBUG.error("unable to get IDP meta alias from request.");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw new WSFederationException(BUNDLE_NAME, "IDPMetaAliasNotFound", null);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major WSFederationMetaManager metaManager = WSFederationUtils.getMetaManager();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major realm = WSFederationMetaUtils.getRealmByMetaAlias(metaAlias);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final String idpEntityId = metaManager.getEntityByMetaAlias(metaAlias);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (StringUtils.isEmpty(idpEntityId)) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DEBUG.error("Unable to get IDP Entity ID from metaAlias");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw new WSFederationException(BUNDLE_NAME, "nullIDPEntityID", null);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final IDPSSOConfigElement idpConfig = metaManager.getIDPSSOConfig(realm, idpEntityId);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (idpConfig == null) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DEBUG.error("Cannot find configuration for IdP " + idpEntityId);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw new WSFederationException(BUNDLE_NAME, "unableToFindIDPConfiguration", null);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final boolean activeRequestorEnabled = Boolean.parseBoolean(WSFederationMetaUtils.getAttribute(idpConfig,
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major ACTIVE_REQUESTOR_PROFILE_ENABLED));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (!activeRequestorEnabled) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DEBUG.warning("Active Requestor Profile is not enabled for the hosted IdP {}", idpEntityId);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major response.sendError(HttpServletResponse.SC_NOT_FOUND);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major return;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major // We can process the SOAP request now.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major SAMLUtils.checkHTTPContentLength(request);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major MimeHeaders headers = SOAPCommunicator.getInstance().getHeaders(request);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major SOAPMessage soapFault;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major SSOToken ssoToken = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major try (InputStream is = request.getInputStream()) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major SOAPMessage soapMessage = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL)
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major .createMessage(headers, is);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (DEBUG.messageEnabled()) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major ByteArrayOutputStream baos = new ByteArrayOutputStream();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major soapMessage.writeTo(baos);
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Major DEBUG.message("SOAP message received: " + maskPassword(new String(baos.toByteArray(),
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Major StandardCharsets.UTF_8)));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major parseAndValidateRequest(soapMessage, idpConfig);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major ssoToken = authenticateEndUser(soapMessage, WSFederationMetaUtils.getAttribute(idpConfig,
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major AUTHENTICATOR_CLASS, "org.forgerock.openam.saml2.plugins.DefaultWsFedAuthenticator"));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final SAML11RequestedSecurityToken requestedSecurityToken = WSFederationUtils.createSAML11Token(realm,
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major idpEntityId, address, ssoToken, address, SAMLConstants.AUTH_METHOD_PASSWORD_URI, true);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final Assertion assertion = requestedSecurityToken.getAssertion();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major request.setAttribute("inResponseTo", ESAPI.encoder().encodeForXML(messageId));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final Date responseCreated = newDate();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major request.setAttribute("responseCreated", ESAPI.encoder().encodeForXML(
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DateUtils.dateToString(responseCreated)));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major request.setAttribute("responseExpires", ESAPI.encoder().encodeForXML(
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DateUtils.dateToString(newDate(responseCreated.getTime() + 300 * 1000))));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major request.setAttribute("notBefore", ESAPI.encoder().encodeForXML(
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DateUtils.dateToString(assertion.getConditions().getNotBefore())));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major request.setAttribute("notOnOrAfter", ESAPI.encoder().encodeForXML(
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DateUtils.dateToString(assertion.getConditions().getNotOnorAfter())));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major request.setAttribute("targetAddress", ESAPI.encoder().encodeForXML(address));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major request.setAttribute("requestedSecurityToken", requestedSecurityToken.toString());
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major request.setAttribute("assertionId", ESAPI.encoder().encodeForXML(assertion.getAssertionID()));
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major request.getRequestDispatcher("/wsfederation/jsp/activeresponse.jsp").forward(request, response);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major return;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } catch (ActiveRequestorException are) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DEBUG.message("An error occurred while processing the Active Request", are);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major soapFault = are.getSOAPFault();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } catch (SOAPException | WSFederationException ex) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DEBUG.error("An unexpected error occurred while processing the SOAP message", ex);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major soapFault = newReceiverException(ex).getSOAPFault();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } finally {
2eb3d167edaf486620a87bd4c227bd1a4356a6d5Peter Major if (ssoToken != null) {
2eb3d167edaf486620a87bd4c227bd1a4356a6d5Peter Major try {
2eb3d167edaf486620a87bd4c227bd1a4356a6d5Peter Major SessionManager.getProvider().invalidateSession(ssoToken, request, response);
2eb3d167edaf486620a87bd4c227bd1a4356a6d5Peter Major } catch (SessionException se) {
2eb3d167edaf486620a87bd4c227bd1a4356a6d5Peter Major DEBUG.message("Unable to invalidate temporary session", se);
2eb3d167edaf486620a87bd4c227bd1a4356a6d5Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (soapFault != null) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major OutputStream os = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major try {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (soapFault.saveRequired()) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major soapFault.saveChanges();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major SAML2Utils.putHeaders(soapFault.getMimeHeaders(), response);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major os = response.getOutputStream();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major soapFault.writeTo(os);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major os.flush();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } catch (SOAPException se) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DEBUG.error("An error occurred while sending back SOAP fault:", se);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } finally {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major IOUtils.closeIfNotNull(os);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } else {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major // This can happen if we failed to create the SOAP Fault for some reason.
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private void parseAndValidateRequest(SOAPMessage soapMessage, IDPSSOConfigElement idpConfig) throws SOAPException,
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major WSFederationException {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final SOAPHeader soapHeader = soapMessage.getSOAPHeader();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final NodeList headerNodes = soapHeader.getChildNodes();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major String action = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major String to = null;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major for (int i = 0; i < headerNodes.getLength(); i++) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final Node node = headerNodes.item(i);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (node instanceof Element) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final Element element = (Element) node;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (WSA_NAMESPACE.equals(element.getNamespaceURI())) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final String textContent = element.getTextContent();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if ("Action".equals(element.getLocalName())) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major action = textContent;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } else if ("To".equals(element.getLocalName())) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major to = textContent;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } else if ("MessageID".equals(element.getLocalName())) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major messageId = textContent;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } else if (WSSE_NAMESPACE.equals(element.getNamespaceURI())) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if ("Security".equals(element.getLocalName())) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major extractSecurityDetails(element);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final String stsEndpoint = WSFederationMetaUtils.getEndpointBaseUrl(idpConfig, request)
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major + "/WSFederationServlet/sts/metaAlias" + idpConfig.getMetaAlias();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final Date expiresDate;
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major try {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major expiresDate = DateUtils.stringToDate(expires);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } catch (ParseException pe) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newSenderException("invalidOrExpiredRequest");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (!ACTION.equals(action)) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newSenderException("invalidValueForElement", "wsa:Action");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } else if (StringUtils.isEmpty(username) || password.length == 0) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newSenderException("unableToAuthenticate");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } else if (newDate().after(expiresDate)) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newSenderException("timeInvalid");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } else {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major try {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major URLPatternMatcher patternMatcher = new URLPatternMatcher();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (!patternMatcher.match(stsEndpoint, Collections.singleton(to), false)) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newSenderException("invalidValueForElement", "wsa:To");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } catch (MalformedURLException murle) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newSenderException("invalidValueForElement", "wsa:To");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final SOAPBody soapBody = soapMessage.getSOAPBody();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final String requestType = getSingleElement(soapBody, WST_NAMESPACE, "RequestType");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (!REQUEST_TYPE.equals(requestType)) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newReceiverException("unsupportedRequestType");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major address = getSingleElement(soapBody, WSA_NAMESPACE, "Address");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final List<String> trustedAddresses = WSFederationMetaUtils.getAttributes(idpConfig, TRUSTED_ADDRESSES);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (trustedAddresses == null || !trustedAddresses.contains(address)) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newReceiverException("invalidReceiver");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final String keyType = getSingleElement(soapBody, WST_NAMESPACE, "KeyType");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (!NO_PROOF_KEY_KEY_TYPE.equals(keyType)) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newReceiverException("unsupportedKeyType");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private SSOToken authenticateEndUser(SOAPMessage soapMessage, String authenticator)
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throws ActiveRequestorException {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major try {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major final WsFedAuthenticator wsFedAuthenticator = Class.forName(authenticator)
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major .asSubclass(WsFedAuthenticator.class).newInstance();
1d684f1accbc962da075532ff3b1ad66459dd750Peter Major request.setAttribute(Constants.WSFED_ACTIVE_LOGIN, true);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major return wsFedAuthenticator.authenticate(request, response, soapMessage, realm, username, password);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } catch (ReflectiveOperationException roe) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major DEBUG.error("An error occurred while invoking WsFedAuthenticator", roe);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newReceiverException(roe);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private void extractSecurityDetails(Element element) throws WSFederationException {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major username = getSingleElement(element, WSSE_NAMESPACE, "Username");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major password = getSingleElement(element, WSSE_NAMESPACE, "Password").toCharArray();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major expires = getSingleElement(element, WSU_NAMESPACE, "Expires");
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major private String getSingleElement(Element element, String namespaceURI, String localName)
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throws WSFederationException {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major NodeList nodeList = element.getElementsByTagNameNS(namespaceURI, localName);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major if (nodeList.getLength() == 0) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newSenderException("missingElement", localName, namespaceURI);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } else if (nodeList.getLength() > 1) {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major throw newSenderException("tooManyElements", localName, namespaceURI);
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major } else {
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major return nodeList.item(0).getTextContent();
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major }
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Major
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Major private String maskPassword(String text) {
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Major int start = text.indexOf("Password>");
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Major int end = text.lastIndexOf("<", text.lastIndexOf("Password>"));
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Major
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Major return text.substring(0, start + "Password>".length()) + "### MASKED PASSWORD ###" + text.substring(end);
ac53d20f2b6fe218ec0103160afc5c443a058b0ePeter Major }
0748565aad6a8878aecb88a26081c9bb10c00279Peter Major}