public URI generateRedirectUri(String samlParameterName, String redirectUri, Document document)
      throws ConfigurationException, ProcessingException, IOException {
    KeycloakUriBuilder builder =
        KeycloakUriBuilder.fromUri(redirectUri)
            .replaceQuery(null)
            .queryParam(samlParameterName, base64Encoded(document));
    if (relayState != null) {
      builder.queryParam("RelayState", relayState);
    }

    if (sign) {
      builder.queryParam(
          GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, signatureAlgorithm.getXmlSignatureMethod());
      URI uri = builder.build();
      String rawQuery = uri.getRawQuery();
      Signature signature = signatureAlgorithm.createSignature();
      byte[] sig = new byte[0];
      try {
        signature.initSign(signingKeyPair.getPrivate());
        signature.update(rawQuery.getBytes("UTF-8"));
        sig = signature.sign();
      } catch (InvalidKeyException | UnsupportedEncodingException | SignatureException e) {
        throw new ProcessingException(e);
      }
      String encodedSig = RedirectBindingUtil.base64URLEncode(sig);
      builder.queryParam(GeneralConstants.SAML_SIGNATURE_REQUEST_KEY, encodedSig);
    }
    return builder.build();
  }
 public URI getAuthServerRoot() {
   try {
     return KeycloakUriBuilder.fromUri(suiteContext.getAuthServerInfo().getContextRoot().toURI())
         .path("/auth/")
         .build();
   } catch (URISyntaxException e) {
     throw new RuntimeException(e);
   }
 }
 /**
  * This function has been copied (and modified) from the Keycloak AdapterDeploymentContext class.
  * It should be kept up-to-date with future versions of Keycloak.
  */
 private KeycloakUriBuilder getBaseBuilder(
     KeycloakDeployment deployment, HttpFacade.Request facadeRequest) {
   String base = deployment.getAuthServerBaseUrl();
   KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(base);
   URI request = URI.create(facadeRequest.getURI());
   String scheme = request.getScheme();
   if (deployment.getSslRequired().isRequired(facadeRequest.getRemoteAddr())) {
     scheme = "https";
     if (!request.getScheme().equals(scheme) && request.getPort() != -1) {
       throw new RuntimeException("Can't resolve relative url from adapter config.");
     }
   }
   builder.scheme(scheme);
   builder.host(request.getHost());
   if (request.getPort() != -1) {
     builder.port(request.getPort());
   }
   return builder;
 }
  public void verifyRedirectBindingSignature(PublicKey publicKey, String paramKey)
      throws VerificationException {
    String request = facade.getRequest().getQueryParamValue(paramKey);
    String algorithm =
        facade.getRequest().getQueryParamValue(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY);
    String signature =
        facade.getRequest().getQueryParamValue(GeneralConstants.SAML_SIGNATURE_REQUEST_KEY);
    String decodedAlgorithm =
        facade.getRequest().getQueryParamValue(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY);

    if (request == null) {
      throw new VerificationException("SAML Request was null");
    }
    if (algorithm == null) throw new VerificationException("SigAlg was null");
    if (signature == null) throw new VerificationException("Signature was null");

    // Shibboleth doesn't sign the document for redirect binding.
    // todo maybe a flag?

    String relayState = facade.getRequest().getQueryParamValue(GeneralConstants.RELAY_STATE);
    KeycloakUriBuilder builder = KeycloakUriBuilder.fromPath("/").queryParam(paramKey, request);
    if (relayState != null) {
      builder.queryParam(GeneralConstants.RELAY_STATE, relayState);
    }
    builder.queryParam(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, algorithm);
    String rawQuery = builder.build().getRawQuery();

    try {
      // byte[] decodedSignature = RedirectBindingUtil.urlBase64Decode(signature);
      byte[] decodedSignature = Base64.decode(signature);

      SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.getFromXmlMethod(decodedAlgorithm);
      Signature validator = signatureAlgorithm.createSignature(); // todo plugin signature alg
      validator.initVerify(publicKey);
      validator.update(rawQuery.getBytes("UTF-8"));
      if (!validator.verify(decodedSignature)) {
        throw new VerificationException("Invalid query param signature");
      }
    } catch (Exception e) {
      throw new VerificationException(e);
    }
  }
 @Override
 public String getRedirectUri() {
   HttpSession session = request.getSession(false);
   if (session == null) return null;
   String redirect = (String) session.getAttribute(REDIRECT_URI);
   if (redirect == null) {
     String contextPath = request.getContextPath();
     String baseUri =
         KeycloakUriBuilder.fromUri(request.getRequestURL().toString())
             .replacePath(contextPath)
             .build()
             .toString();
     return SamlUtil.getRedirectTo(facade, contextPath, baseUri);
   }
   return redirect;
 }
 void setAuthServerBaseUrl(String authServerBaseUrl) {
   this.authServerBaseUrl = authServerBaseUrl;
   KeycloakUriBuilder serverBuilder = KeycloakUriBuilder.fromUri(authServerBaseUrl);
   resolveUrls(serverBuilder);
 }
 private static String getContextPath(HttpFacade facade) {
   String uri = facade.getRequest().getURI();
   String path = KeycloakUriBuilder.fromUri(uri).getPath();
   int index = path.indexOf("/", 1);
   return index == -1 ? path : path.substring(0, index);
 }