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: SAMLPOSTProfileServlet.java,v 1.4 2009/06/12 22:21:39 mallas Exp $
7bed76a091ac06e51ede059942f9ebc9d9a3166aNeil Madden * Portions Copyrighted 2011-2016 ForgeRock AS
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.session.SessionException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.session.SessionManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.session.SessionProvider;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.assertion.Assertion;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLConstants;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLServiceManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.protocol.StatusCode;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This servlet is used to support SAML 1.x Web Browser/POST Profile.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpublic class SAMLPOSTProfileServlet extends HttpServlet {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Initiates <code>SAML</code> web browser POST profile.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This method takes in a TARGET in the request, creates a SAMLResponse,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * then redirects user to the destination site.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param request <code>HttpServletRequest</code> instance
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param response <code>HttpServletResponse</code> instance
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws ServletException if there is an error.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws IOException if there is an error.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void doGet(HttpServletRequest request, HttpServletResponse response)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("nullInputParameter")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "nullInputParameter",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("nullInputParameter"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get Session
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster response.sendRedirect(SAMLUtils.getLoginRedirectURL(request));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // obtain TARGET
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String target = request.getParameter(SAMLConstants.POST_TARGET_PARAM);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("missingTargetSite")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "missingTargetSite",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("missingTargetSite"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Get the Destination site Entry
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // find the destSite POST URL, which is the Receipient
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLServiceManager.SiteEntry destSite = getDestSite(target);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ((destSiteUrl = destSite.getPOSTUrl()) == null)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("targetForbidden"),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "targetForbidden",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("targetForbidden") + " " + target);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int majorVersion = SAMLConstants.PROTOCOL_MAJOR_VERSION;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int minorVersion = SAMLConstants.PROTOCOL_MINOR_VERSION;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringTokenizer st = new StringTokenizer(version,".");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster majorVersion = Integer.parseInt(st.nextToken().trim());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster minorVersion = Integer.parseInt(st.nextToken().trim());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // create assertion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AssertionManager am = AssertionManager.getInstance();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SessionProvider sessionProvider = SessionManager.getProvider();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster request, response, destSite.getSourceID(), target,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // create SAMLResponse
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster samlResponse = new Response(null, status, destSiteUrl, contents);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.doGet: Exception "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "couldNotCreateResponse",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.doGet: Exception "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "couldNotCreateResponse",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.doGet: Exception "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "couldNotCreateResponse",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // sign the samlResponse
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("SAMLPOSTProfileServlet.doGet: " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "signed samlResponse is" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signedBytes = SAMLUtils.getResponseBytes(samlResponse);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.doGet: Exception "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "when signing the response:", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "errorSigningResponse",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("errorSigningResponse"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // base64 encode the signed samlResponse
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster encodedResponse = Base64.encode(signedBytes, true).trim();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.doGet: Exception "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "when encoding the response:", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "errorEncodeResponse",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("errorEncodeResponse"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (LogUtils.isAccessLoggable(java.util.logging.Level.FINE)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("redirectTo"),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster target, destSiteUrl, new String(signedBytes, "UTF-8")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("redirectTo"),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster response.setContentType("text/html; charset=UTF-8");
7bed76a091ac06e51ede059942f9ebc9d9a3166aNeil Madden out.println("<BODY Onload=\"document.forms[0].submit()\">");
7bed76a091ac06e51ede059942f9ebc9d9a3166aNeil Madden + ESAPI.encoder().encodeForHTMLAttribute(destSiteUrl) + "\">");
7bed76a091ac06e51ede059942f9ebc9d9a3166aNeil Madden SAMLConstants.POST_SAML_RESPONSE_PARAM + "\" ");
7bed76a091ac06e51ede059942f9ebc9d9a3166aNeil Madden out.println("VALUE=\"" + ESAPI.encoder().encodeForHTMLAttribute(encodedResponse) + "\">");
7bed76a091ac06e51ede059942f9ebc9d9a3166aNeil Madden SAMLConstants.POST_TARGET_PARAM + "\" VALUE=\"" + ESAPI.encoder().encodeForHTMLAttribute(target)
7bed76a091ac06e51ede059942f9ebc9d9a3166aNeil Madden + "\"> </FORM>");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private SAMLServiceManager.SiteEntry getDestSite(String target) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.getDestSite:"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + " missing host in target.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // loop through the trusted server list and try to find the server
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLServiceManager.SiteEntry serverSite = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Iterator iter = ((Set) SAMLServiceManager.getAttribute(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLConstants.TRUSTED_SERVER_LIST)).iterator();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster serverSite = (SAMLServiceManager.SiteEntry) iter.next();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.getDestSite: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + " No destSite found from the target.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.getDestSite: ", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private Object getSession(HttpServletRequest request) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.getSession: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "Session is null.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.getSession: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "Session is invalid.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.getSession: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This method processes TARGET and SAMLResponse info from the request,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * validates the response/assertion(s), then redirects user to the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * TARGET resource if all are valid.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param request <code>HttpServletRequest</code> instance
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param response <code>HttpServletResponse</code> instance
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws ServletException if there is an error.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws IOException if there is an error.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void doPost(HttpServletRequest request, HttpServletResponse response)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster response.setContentType("text/html; charset=UTF-8");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("nullInputParameter")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "nullInputParameter",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("nullInputParameter"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // obtain TARGET
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String target = request.getParameter(SAMLConstants.POST_TARGET_PARAM);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("missingTargetSite")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "missingTargetSite",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("missingTargetSite"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // obtain SAMLResponse
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("missingSAMLResponse")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "missingSAMLResponse",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("missingSAMLResponse"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // decode the Response
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("SAMLPOSTProfileServlet.doPost: Exception "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "when decoding SAMLResponse:", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "errorDecodeResponse",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("errorDecodeResponse"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Get Response back
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Response sResponse = SAMLUtils.getResponse(raw);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("errorObtainResponse")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "errorObtainResponse",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("errorObtainResponse"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("SAMLPOSTProfileServlet.doPost: Received "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // verify that Response is correct
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer requestUrl = request.getRequestURL();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("SAMLPOSTProfileServlet.doPost: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean valid = SAMLUtils.verifyResponse(sResponse,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("invalidResponse")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "invalidResponse",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("invalidResponse"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster javax.security.auth.Subject authSubject = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Object token = SAMLUtils.generateSession(request,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.error("generateSession: ", ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "failedCreateSSOToken")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "failedCreateSSOToken",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (LogUtils.isAccessLoggable(java.util.logging.Level.FINE)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("accessGranted"),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] data = {SAMLUtils.bundle.getString("accessGranted")};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("POST to target:"+target);