/** * Handles the request for http post binding * * @param request The HTTP request with SAML2 message * @param response The HTTP response * @param isLogout Whether the request is a logout request * @throws SSOAgentException */ public String buildPostRequest( HttpServletRequest request, HttpServletResponse response, boolean isLogout) throws SSOAgentException { RequestAbstractType requestMessage = null; if (!isLogout) { requestMessage = buildAuthnRequest(request); if (ssoAgentConfig.getSAML2().isRequestSigned()) { requestMessage = SSOAgentUtils.setSignature( (AuthnRequest) requestMessage, XMLSignature.ALGO_ID_SIGNATURE_RSA, new X509CredentialImpl(ssoAgentConfig.getSAML2().getSSOAgentX509Credential())); } } else { LoggedInSessionBean sessionBean = (LoggedInSessionBean) request.getSession(false).getAttribute(SSOAgentConstants.SESSION_BEAN_NAME); if (sessionBean != null) { requestMessage = buildLogoutRequest( sessionBean.getSAML2SSO().getSubjectId(), sessionBean.getSAML2SSO().getSessionIndex()); if (ssoAgentConfig.getSAML2().isRequestSigned()) { requestMessage = SSOAgentUtils.setSignature( (LogoutRequest) requestMessage, XMLSignature.ALGO_ID_SIGNATURE_RSA, new X509CredentialImpl(ssoAgentConfig.getSAML2().getSSOAgentX509Credential())); } } else { throw new SSOAgentException("SLO Request can not be built. SSO Session is null"); } } String encodedRequestMessage = encodeRequestMessage(requestMessage, SAMLConstants.SAML2_POST_BINDING_URI); Map<String, String[]> paramsMap = new HashMap<String, String[]>(); paramsMap.put( SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_AUTH_REQ, new String[] {encodedRequestMessage}); if (ssoAgentConfig.getSAML2().getRelayState() != null) { paramsMap.put( RelayState.DEFAULT_ELEMENT_LOCAL_NAME, new String[] {ssoAgentConfig.getSAML2().getRelayState()}); } // Add any additional parameters defined if (ssoAgentConfig.getQueryParams() != null && !ssoAgentConfig.getQueryParams().isEmpty()) { paramsMap.putAll(ssoAgentConfig.getQueryParams()); } StringBuilder htmlParams = new StringBuilder(); for (Map.Entry<String, String[]> entry : paramsMap.entrySet()) { if (entry.getKey() != null && entry.getValue() != null && entry.getValue().length > 0) { for (String param : entry.getValue()) { htmlParams .append("<input type='hidden' name='") .append(entry.getKey()) .append("' value='") .append(param) .append("'>\n"); } } } String htmlPayload = ssoAgentConfig.getSAML2().getPostBindingRequestHTMLPayload(); if (htmlPayload == null || !htmlPayload.contains("<!--$saml_params-->")) { htmlPayload = "<html>\n" + "<body>\n" + "<p>You are now redirected back to " + ssoAgentConfig.getSAML2().getIdPURL() + " \n" + "If the redirection fails, please click the post button.</p>\n" + "<form method='post' action='" + ssoAgentConfig.getSAML2().getIdPURL() + "'>\n" + "<p>\n" + htmlParams.toString() + "<button type='submit'>POST</button>\n" + "</p>\n" + "</form>\n" + "<script type='text/javascript'>\n" + "document.forms[0].submit();\n" + "</script>\n" + "</body>\n" + "</html>"; } else { htmlPayload = htmlPayload.replace("<!--$saml_params-->", htmlParams.toString()); } return htmlPayload; }
protected void processSSOResponse(HttpServletRequest request) throws SSOAgentException { LoggedInSessionBean sessionBean = new LoggedInSessionBean(); sessionBean.setSAML2SSO(sessionBean.new SAML2SSO()); String saml2ResponseString = new String( Base64.decode( request.getParameter(SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_RESP)), Charset.forName("UTF-8")); Response saml2Response = (Response) SSOAgentUtils.unmarshall(saml2ResponseString); sessionBean.getSAML2SSO().setResponseString(saml2ResponseString); sessionBean.getSAML2SSO().setSAMLResponse(saml2Response); Assertion assertion = null; if (ssoAgentConfig.getSAML2().isAssertionEncrypted()) { List<EncryptedAssertion> encryptedAssertions = saml2Response.getEncryptedAssertions(); EncryptedAssertion encryptedAssertion = null; if (!org.apache.commons.collections.CollectionUtils.isEmpty(encryptedAssertions)) { encryptedAssertion = encryptedAssertions.get(0); try { assertion = getDecryptedAssertion(encryptedAssertion); } catch (Exception e) { if (log.isDebugEnabled()) { log.debug("Assertion decryption failure : ", e); } throw new SSOAgentException("Unable to decrypt the SAML2 Assertion"); } } } else { List<Assertion> assertions = saml2Response.getAssertions(); if (assertions != null && !assertions.isEmpty()) { assertion = assertions.get(0); } } if (assertion == null) { if (isNoPassive(saml2Response)) { LOGGER.log(Level.FINE, "Cannot authenticate in passive mode"); return; } throw new SSOAgentException("SAML2 Assertion not found in the Response"); } String idPEntityIdValue = assertion.getIssuer().getValue(); if (idPEntityIdValue == null || idPEntityIdValue.isEmpty()) { throw new SSOAgentException("SAML2 Response does not contain an Issuer value"); } else if (!idPEntityIdValue.equals(ssoAgentConfig.getSAML2().getIdPEntityId())) { throw new SSOAgentException("SAML2 Response Issuer verification failed"); } sessionBean.getSAML2SSO().setAssertion(assertion); // Cannot marshall SAML assertion here, before signature validation due to a weird issue in // OpenSAML // Get the subject name from the Response Object and forward it to login_action.jsp String subject = null; if (assertion.getSubject() != null && assertion.getSubject().getNameID() != null) { subject = assertion.getSubject().getNameID().getValue(); } if (subject == null) { throw new SSOAgentException("SAML2 Response does not contain the name of the subject"); } sessionBean.getSAML2SSO().setSubjectId(subject); // set the subject request.getSession().setAttribute(SSOAgentConstants.SESSION_BEAN_NAME, sessionBean); // validate audience restriction validateAudienceRestriction(assertion); // validate signature validateSignature(saml2Response, assertion); // Marshalling SAML2 assertion after signature validation due to a weird issue in OpenSAML sessionBean.getSAML2SSO().setAssertionString(marshall(assertion)); ((LoggedInSessionBean) request.getSession().getAttribute(SSOAgentConstants.SESSION_BEAN_NAME)) .getSAML2SSO() .setSubjectAttributes(getAssertionStatements(assertion)); // For removing the session when the single sign out request made by the SP itself if (ssoAgentConfig.getSAML2().isSLOEnabled()) { String sessionId = assertion.getAuthnStatements().get(0).getSessionIndex(); if (sessionId == null) { throw new SSOAgentException( "Single Logout is enabled but IdP Session ID not found in SAML2 Assertion"); } ((LoggedInSessionBean) request.getSession().getAttribute(SSOAgentConstants.SESSION_BEAN_NAME)) .getSAML2SSO() .setSessionIndex(sessionId); SSOAgentSessionManager.addAuthenticatedSession(request.getSession(false)); } request.getSession().setAttribute(SSOAgentConstants.SESSION_BEAN_NAME, sessionBean); }
/** * Returns the redirection URL with the appended SAML2 Request message * * @param request SAML 2 request * @return redirectionUrl */ public String buildRedirectRequest(HttpServletRequest request, boolean isLogout) throws SSOAgentException { RequestAbstractType requestMessage = null; if (!isLogout) { requestMessage = buildAuthnRequest(request); } else { LoggedInSessionBean sessionBean = (LoggedInSessionBean) request.getSession(false).getAttribute(SSOAgentConstants.SESSION_BEAN_NAME); if (sessionBean != null) { requestMessage = buildLogoutRequest( sessionBean.getSAML2SSO().getSubjectId(), sessionBean.getSAML2SSO().getSessionIndex()); } else { throw new SSOAgentException("SLO Request can not be built. SSO Session is NULL"); } } String idpUrl = null; String encodedRequestMessage = encodeRequestMessage(requestMessage, SAMLConstants.SAML2_REDIRECT_BINDING_URI); StringBuilder httpQueryString = new StringBuilder( SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_AUTH_REQ + "=" + encodedRequestMessage); String relayState = ssoAgentConfig.getSAML2().getRelayState(); if (relayState != null) { try { httpQueryString.append( "&" + RelayState.DEFAULT_ELEMENT_LOCAL_NAME + "=" + URLEncoder.encode(relayState, "UTF-8").trim()); } catch (UnsupportedEncodingException e) { throw new SSOAgentException( "Error occurred while URLEncoding " + RelayState.DEFAULT_ELEMENT_LOCAL_NAME, e); } } if (ssoAgentConfig.getQueryParams() != null && !ssoAgentConfig.getQueryParams().isEmpty()) { StringBuilder builder = new StringBuilder(); for (Map.Entry<String, String[]> entry : ssoAgentConfig.getQueryParams().entrySet()) { if (entry.getKey() != null && entry.getValue() != null && entry.getValue().length > 0) { for (String param : entry.getValue()) { builder.append("&").append(entry.getKey()).append("=").append(param); } } } httpQueryString.append(builder); } if (ssoAgentConfig.getSAML2().isRequestSigned()) { SSOAgentUtils.addDeflateSignatureToHTTPQueryString( httpQueryString, new X509CredentialImpl(ssoAgentConfig.getSAML2().getSSOAgentX509Credential())); } if (ssoAgentConfig.getSAML2().getIdPURL().indexOf("?") > -1) { idpUrl = ssoAgentConfig.getSAML2().getIdPURL().concat("&").concat(httpQueryString.toString()); } else { idpUrl = ssoAgentConfig.getSAML2().getIdPURL().concat("?").concat(httpQueryString.toString()); } return idpUrl; }