/* * Copyright 2016 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.keycloak.adapters.saml; import org.keycloak.adapters.spi.HttpFacade; import org.keycloak.saml.BaseSAML2BindingBuilder; import org.keycloak.saml.common.constants.GeneralConstants; import org.keycloak.saml.common.exceptions.ConfigurationException; import org.keycloak.saml.common.exceptions.ProcessingException; import org.w3c.dom.Document; import java.io.IOException; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public class SamlUtil { public static void sendSaml(boolean asRequest, HttpFacade httpFacade, String actionUrl, BaseSAML2BindingBuilder binding, Document document, SamlDeployment.Binding samlBinding) throws ProcessingException, ConfigurationException, IOException { if (samlBinding == SamlDeployment.Binding.POST) { String html = asRequest ? binding.postBinding(document).getHtmlRequest(actionUrl) : binding.postBinding(document).getHtmlResponse(actionUrl) ; httpFacade.getResponse().setStatus(200); httpFacade.getResponse().setHeader("Content-Type", "text/html"); httpFacade.getResponse().setHeader("Pragma", "no-cache"); httpFacade.getResponse().setHeader("Cache-Control", "no-cache, no-store"); httpFacade.getResponse().getOutputStream().write(html.getBytes(GeneralConstants.SAML_CHARSET)); httpFacade.getResponse().end(); } else { String uri = asRequest ? binding.redirectBinding(document).requestURI(actionUrl).toString() : binding.redirectBinding(document).responseURI(actionUrl).toString(); httpFacade.getResponse().setStatus(302); httpFacade.getResponse().setHeader("Location", uri); httpFacade.getResponse().end(); } } /** * Gets a url to redirect to if there is an IDP initiated login. Looks for a redirectTo query param first, then looks * in RelayState, if not in either defaults to context path. * * @param facade * @param contextPath * @param baseUri * @return */ public static String getRedirectTo(HttpFacade facade, String contextPath, String baseUri) { String redirectTo = facade.getRequest().getQueryParamValue("redirectTo"); if (redirectTo != null && !redirectTo.isEmpty()) { return buildRedirectTo(baseUri, redirectTo); } else { redirectTo = facade.getRequest().getFirstParam(GeneralConstants.RELAY_STATE); if (redirectTo != null) { int index = redirectTo.indexOf("redirectTo="); if (index >= 0) { String to = redirectTo.substring(index + "redirectTo=".length()); index = to.indexOf(';'); if (index >=0) { to = to.substring(0, index); } return buildRedirectTo(baseUri, to); } } if (contextPath.isEmpty()) baseUri += "/"; return baseUri; } } private static String buildRedirectTo(String baseUri, String redirectTo) { if (redirectTo.startsWith("/")) redirectTo = redirectTo.substring(1); if (baseUri.endsWith("/")) baseUri = baseUri.substring(0, baseUri.length() - 1); redirectTo = baseUri + "/" + redirectTo; return redirectTo; } }