a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * of the Common Development and Distribution License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * (the License). You may not use this file except in
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You can obtain a copy of the License at
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See the License for the specific language governing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * permission and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Header Notice in each file and include the License file
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below the CDDL Header,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * with the fields enclosed by brackets [] replaced by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * your own identifying information:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * $Id: SOAPReceiver.java,v 1.3 2008/06/25 05:47:23 qcheng Exp $
4a5a82da9bbab0a3ea1701c3ae9334c678d24ca5Mark de Reeper * Portions Copyrighted 2013 ForgeRock, Inc.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpackage com.sun.identity.liberty.ws.soapbinding;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.liberty.ws.security.SecurityUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.liberty.ws.common.LogUtil;
4a5a82da9bbab0a3ea1701c3ae9334c678d24ca5Mark de Reeperimport org.forgerock.openam.utils.ClientUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The <code>SOAPReceiver</code> class defines a SOAP Receiver which supports
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * SOAP over HTTP binding. It receives requests sent from <code>Client</code>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * During the startup, it will read <code>RequestHandler</code> from SOAP
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * binding SM schema and store in a static HashMap. Each
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>RequestHandler</code> is associated with a unique key. When a web
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * service client uses <code>Client</code> to send request, the SOAP URL must
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * be in the format of 'this_servlet_URL>/key'. The <code>SOAPReceiver</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * will parse the SOAP URL to get the key and use it to find corresponding
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>RequestHandler</code>. After it is done processing, it will invoke
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>RequestHandler.processRequest</code> to let web service to do further
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * processing.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static MessageFactory msgFactory = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Initializes the Servlet.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param config the <code>ServletConfig</code>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws ServletException if there is any error.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void init(ServletConfig config) throws ServletException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Utils.debug.error("SOAPReceiver.init: create message " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "factory failed.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Processes HTTP request and sends back HTTP response. It gets called
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * internally by the servlet engine.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param request the HTTP request.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param response the HTTP response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws IOException if an IO error occurs while processing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws ServletException if an servlet error occurs while processing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the request
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void doPost(HttpServletRequest request,HttpServletResponse response)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster MimeHeaders mimeHeaders = SAMLUtils.getMimeHeaders(request);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ServletInputStream sInputStream = request.getInputStream();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SOAPMessage soapMessage = msgFactory.createMessage(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SOAPMessage soapMessageReply = this.onMessage(soapMessage,request);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ServletOutputStream sOutputStream = response.getOutputStream();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Processes the request message and invokes
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>RequestHandler.processRequest</code>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param message request received from the requestor
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param request the HTTP request
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return response being sent to the requestor
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public SOAPMessage onMessage(SOAPMessage message,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Utils.debug.message("SOAPReceiver.onMessage:");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster request.getHeader(SOAPBindingConstants.SOAP_ACTION_HEADER);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (soapAction != null && soapAction.length() == 0) {
4a5a82da9bbab0a3ea1701c3ae9334c678d24ca5Mark de Reeper String remoteAddr = ClientUtils.getClientIPAddress(request);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster X509Certificate[] allCerts = (X509Certificate[])
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster request.getAttribute("javax.servlet.request.X509Certificate");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // remove leading '/'
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Utils.debug.message("SOAPReceiver.doPost: key = " + key +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (RequestHandler)SOAPBindingService.handlers.get(key);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (List)SOAPBindingService.supportedSOAPActionsMap
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return FormSOAPError("Client","unsupportedSOAPAction",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (req.getSecurityProfileType() != Message.ANONYMOUS &&
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return FormSOAPError("Client", "cannotVerifySignature",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String authMech = req.getAuthenticationMechanism();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Utils.debug.message("SOAPReceiver.onMessage: " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ", isClientAuthentication = " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return FormSOAPError("Server", "unsupportedAuthMech",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SOAPBindingService.getWebServiceAuthenticator();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return FormSOAPError("Server", "noWSAuthentication",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Object token = wsAuthenticator.authenticate(req, null,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = { req.getCorrelationHeader().getMessageID(),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.access(Level.INFO,LogUtil.WS_SUCCESS,data);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int securityProfileType = resp.getSecurityProfileType();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (securityProfileType == Message.ANONYMOUS ||
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Element sigElem = SecurityUtils.signMessage(resp);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "Unable to sign response");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return FormSOAPError("Server", "unknownError", req);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Utils.debug.message("SOAPReceiver.onMessage: " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Utils.debug.message("SOAPReceiver.onMessage: ", ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Utils.debug.message("SOAPReceiver.onMessage: ", t);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return FormSOAPError("Server", "missingRequestHandler", null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return FormSOAPError("Server", "missingKey", null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Constructs a SOAPMessage with specified fault code and Throwable.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The fault string will be Throwable.getMessage();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The fault code will have same namespace of soap envelope.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param faultCode the fault code
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param throwable the Throwable
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param req the request Message
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the SOAPMessage object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private SOAPMessage FormSOAPError(String faultCode,Throwable throwable,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (faultString == null || faultString.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster faultString = Utils.bundle.getString("unknownError");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return FormSOAPError(req, faultCode, faultString);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Constructs a SOAPMessage with specified fault code and fault string.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The fault code will have same namespace of soap envelope.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param faultCode the fault code
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param faultStringKey the fault string key to resource bundle
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param req the request Message
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the SOAPMessage object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private SOAPMessage FormSOAPError(String faultCode,String faultStringKey,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String faultString = Utils.bundle.getString(faultStringKey);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return FormSOAPError(req, faultCode, faultString);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Constructs a SOAPMessage with specified fault code and fault string.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The fault code will have same namespace of soap envelope.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param req the request Message
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param faultCode the fault code
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param faultString the fault string
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the SOAPMessage object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private SOAPMessage FormSOAPError(Message req, String faultCode,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster logMsg = Utils.bundle.getString("messageID") + "=" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster req.getCorrelationHeader().getMessageID() + ". " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO, LogUtil.WS_FAILURE,data);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster new QName(SOAPBindingConstants.NS_SOAP, faultCode),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e ) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Utils.debug.error("SOAPReceiver.FormSOAPError: ", e);