protected void sendLogoutResponse(Status status, SAMLMessageContext context)
      throws MetadataProviderException, SAMLException, MessageEncodingException {

    SAMLObjectBuilder<LogoutResponse> responseBuilder =
        (SAMLObjectBuilder<LogoutResponse>)
            builderFactory.getBuilder(LogoutResponse.DEFAULT_ELEMENT_NAME);
    LogoutResponse logoutResponse = responseBuilder.buildObject();

    IDPSSODescriptor idpDescriptor = SAMLUtil.getIDPDescriptor(metadata, context.getPeerEntityId());
    SPSSODescriptor spDescriptor = (SPSSODescriptor) context.getLocalEntityRoleMetadata();
    String binding = SAMLUtil.getLogoutBinding(idpDescriptor, spDescriptor);
    SingleLogoutService logoutService = SAMLUtil.getLogoutServiceForBinding(idpDescriptor, binding);

    logoutResponse.setID(generateID());
    logoutResponse.setIssuer(getIssuer(context.getLocalEntityId()));
    logoutResponse.setVersion(SAMLVersion.VERSION_20);
    logoutResponse.setIssueInstant(new DateTime());
    logoutResponse.setInResponseTo(context.getInboundSAMLMessageId());
    logoutResponse.setDestination(logoutService.getLocation());
    logoutResponse.setStatus(status);

    context.setCommunicationProfileId(getProfileIdentifier());
    context.setOutboundMessage(logoutResponse);
    context.setOutboundSAMLMessage(logoutResponse);
    context.setPeerEntityEndpoint(logoutService);

    context.setPeerEntityId(idpDescriptor.getID());
    context.setPeerEntityRoleMetadata(idpDescriptor);

    boolean signMessage = context.getPeerExtendedMetadata().isRequireLogoutResponseSigned();
    sendMessage(context, signMessage);
  }
  public void sendLogoutRequest(SAMLMessageContext context, SAMLCredential credential)
      throws SAMLException, MetadataProviderException, MessageEncodingException {

    // If no user is logged in we do not initialize the protocol.
    if (credential == null) {
      return;
    }

    IDPSSODescriptor idpDescriptor = (IDPSSODescriptor) context.getPeerEntityRoleMetadata();
    SPSSODescriptor spDescriptor = (SPSSODescriptor) context.getLocalEntityRoleMetadata();
    String binding = SAMLUtil.getLogoutBinding(idpDescriptor, spDescriptor);

    SingleLogoutService logoutServiceIDP =
        SAMLUtil.getLogoutServiceForBinding(idpDescriptor, binding);
    LogoutRequest logoutRequest = getLogoutRequest(context, credential, logoutServiceIDP);

    context.setCommunicationProfileId(getProfileIdentifier());
    context.setOutboundMessage(logoutRequest);
    context.setOutboundSAMLMessage(logoutRequest);
    context.setPeerEntityEndpoint(logoutServiceIDP);

    boolean signMessage = context.getPeerExtendedMetadata().isRequireLogoutRequestSigned();
    sendMessage(context, signMessage);

    SAMLMessageStorage messageStorage = context.getMessageStorage();
    if (messageStorage != null) {
      messageStorage.storeMessage(logoutRequest.getID(), logoutRequest);
    }
  }
  /**
   * Initializes SSO by creating AuthnRequest assertion and sending it to the IDP using the default
   * binding. Default IDP is used to send the request.
   *
   * @param options values specified by caller to customize format of sent request
   * @throws SAMLException error initializing SSO
   * @throws SAMLRuntimeException in case context doesn't contain required entities or contains
   *     invalid data
   * @throws MetadataProviderException error retrieving needed metadata
   * @throws MessageEncodingException error forming SAML message
   */
  public void sendAuthenticationRequest(SAMLMessageContext context, WebSSOProfileOptions options)
      throws SAMLException, MetadataProviderException, MessageEncodingException {

    // Verify we deal with a local SP
    if (!SPSSODescriptor.DEFAULT_ELEMENT_NAME.equals(context.getLocalEntityRole())) {
      throw new SAMLException(
          "WebSSO can only be initialized for local SP, but localEntityRole is: "
              + context.getLocalEntityRole());
    }

    // Load the entities from the context
    SPSSODescriptor spDescriptor = (SPSSODescriptor) context.getLocalEntityRoleMetadata();
    IDPSSODescriptor idpssoDescriptor = (IDPSSODescriptor) context.getPeerEntityRoleMetadata();
    ExtendedMetadata idpExtendedMetadata = context.getPeerExtendedMetadata();

    if (spDescriptor == null || idpssoDescriptor == null || idpExtendedMetadata == null) {
      throw new SAMLException(
          "SPSSODescriptor, IDPSSODescriptor or IDPExtendedMetadata are not present in the SAMLContext");
    }
    log.debug(
        "idpExtendedMetadata.getSigningAlgorithm=" + idpExtendedMetadata.getSigningAlgorithm());
    idpExtendedMetadata.setSigningAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512");

    SingleSignOnService ssoService =
        getSingleSignOnService(options, idpssoDescriptor, spDescriptor);
    AssertionConsumerService consumerService =
        getAssertionConsumerService(options, idpssoDescriptor, spDescriptor);

    AuthnRequest authRequest = getAuthnRequest(context, options, consumerService, ssoService);
    if (authRequest == null) {
      throw new SAMLException("Erreur dans getAuthnRequest null");
    }
    // authRequest.setForceAuthn(Boolean.TRUE);
    log.debug("getAuthnRequest.providerName=" + authRequest.getProviderName());
    // TODO optionally implement support for conditions, subject

    context.setCommunicationProfileId(getProfileIdentifier());
    context.setOutboundMessage(authRequest);
    context.setOutboundSAMLMessage(authRequest);
    context.setPeerEntityEndpoint(ssoService);
    context.setPeerEntityRoleMetadata(idpssoDescriptor);
    context.setPeerExtendedMetadata(idpExtendedMetadata);

    if (options.getRelayState() != null) {
      context.setRelayState(options.getRelayState());
    }

    boolean sign =
        spDescriptor.isAuthnRequestsSigned() || idpssoDescriptor.getWantAuthnRequestsSigned();
    log.debug("signature?" + sign + " avec http://www.w3.org/2001/04/xmldsig-more#rsa-sha512");
    context
        .getLocalExtendedMetadata()
        .setSigningAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512");
    sendMessage(context, sign);

    SAMLMessageStorage messageStorage = context.getMessageStorage();
    if (messageStorage != null) {
      messageStorage.storeMessage(authRequest.getID(), authRequest);
    }
  }