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);
    }
  }
예제 #2
0
  @Override
  public Response finishLogout(UserSessionModel userSession) {
    logger.debug("finishLogout");
    String logoutBindingUri = userSession.getNote(SAML_LOGOUT_BINDING_URI);
    if (logoutBindingUri == null) {
      logger.error(
          "Can't finish SAML logout as there is no logout binding set.  Please configure the logout service url in the admin console for your client applications.");
      return ErrorPage.error(session, Messages.FAILED_LOGOUT);
    }
    String logoutRelayState = userSession.getNote(SAML_LOGOUT_RELAY_STATE);
    SAML2LogoutResponseBuilder builder = new SAML2LogoutResponseBuilder();
    builder.logoutRequestID(userSession.getNote(SAML_LOGOUT_REQUEST_ID));
    builder.destination(logoutBindingUri);
    builder.issuer(getResponseIssuer(realm));
    JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder();
    binding.relayState(logoutRelayState);
    String signingAlgorithm = userSession.getNote(SAML_LOGOUT_SIGNATURE_ALGORITHM);
    if (signingAlgorithm != null) {
      SignatureAlgorithm algorithm = SignatureAlgorithm.valueOf(signingAlgorithm);
      String canonicalization = userSession.getNote(SAML_LOGOUT_CANONICALIZATION);
      if (canonicalization != null) {
        binding.canonicalizationMethod(canonicalization);
      }
      KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
      binding
          .signatureAlgorithm(algorithm)
          .signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
          .signDocument();
    }

    try {
      return buildLogoutResponse(userSession, logoutBindingUri, builder, binding);
    } catch (ConfigurationException e) {
      throw new RuntimeException(e);
    } catch (ProcessingException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }