@Override
  public void processRequest(ProfileRequestContext<?, ?> context) throws ExternalAutenticationErrorCodeException {
    final String logId = this.getLogString(context);
    boolean isSignatureService = this.isSignatureServicePeer(context);    

    SignMessageContext signMessageContext = this.getSignMessageContext(context);
    if (signMessageContext == null) {

      // If the peer is a signature service and has only requested a sigmessage LoA we report an error.
      //
      if (isSignatureService) {
        AuthnContextClassContext authnContextClassContext = this.authnContextService.getAuthnContextClassContext(context);
        for (String loa : authnContextClassContext.getAuthnContextClassRefs()) {
          if (this.isSignMessageURI(loa)) {
            log.info("SP has requested '{}' but did not include SignMessage, removing ... [{}]", loa, logId);
            authnContextClassContext.deleteAuthnContextClassRef(loa);
          }
        }
        if (authnContextClassContext.isEmpty()) {
          final String msg = "No valid AuthnContext URI:s were specified in AuthnRequest";
          log.info("{} - can not proceed [{}]", msg, logId);
          throw new ExternalAutenticationErrorCodeException(AuthnEventIds.REQUEST_UNSUPPORTED, msg);
        }
      }
    }
    else {
      // If an ordinary SP included a SignMessage in the request, we simply ignore it.
      //
      if (!isSignatureService) {
        log.warn("Requesting SP is not a signature service, but included SignMessage extension, ignoring ... [{}]", logId);
        AuthenticationContext authnContext = this.getAuthenticationContext(context);
        authnContext.removeSubcontext(SignMessageContext.class);
      }
      // Else, make additional checks and decrypt.
      //
      else {

        // Decrypt the message
        //
        if (signMessageContext.getSignMessage().getEncryptedMessage() != null) {
          try {
            Message cleartextMessage = this.signatureSupportKeyService.decrypt(signMessageContext.getSignMessage());
            log.debug("SignMessage was successfully decrypted [{}]", logId);
            signMessageContext.setClearTextMessage(cleartextMessage);
          }
          catch (DecryptionException e) {
            final String msg = String.format("Failed to decrypt SignMessage - %s", e.getMessage());
            log.error("{} [{}]", msg, logId);
            throw new ExternalAutenticationErrorCodeException(ExtAuthnEventIds.SIGN_MESSAGE_DECRYPTION_ERROR, msg);
          }
        }
        else {
          log.debug("SignMessage was not encrypted [{}]", logId);
        }

        if (!this.supportsMimeType(signMessageContext.getMimeType())) {
          log.warn("IdP does not support display of SignMessage with type '{}' [{}]", signMessageContext.getMimeType(), logId);
          signMessageContext.setDoDisplayMessage(false);

          if (signMessageContext.mustShow()) {
            throw new ExternalAutenticationErrorCodeException(ExtAuthnEventIds.SIGN_MESSAGE_TYPE_NOT_SUPPORTED,
              "Unsupported SignMessage mime type");
          }
        }
        
        // Process (filter, validate, transform) the sign message.
        //
        if (this.signMessagePreProcessor != null && signMessageContext.getClearTextMessage() != null) {
          try {
            String messageToDisplay = this.signMessagePreProcessor.processSignMessage(signMessageContext.getClearTextMessage(), signMessageContext.getMimeType());
            signMessageContext.setMessageToDisplay(messageToDisplay);
          }
          catch (SignMessageContentException e) {
            log.error("Failed to process sign message: {} [{}]", e.getMessage(), logId);
            
            if (signMessageContext.mustShow()) {
              throw new ExternalAutenticationErrorCodeException(AuthnEventIds.REQUEST_UNSUPPORTED, e.getMessage());
            }
            else {
              signMessageContext.setDoDisplayMessage(false);
            }
          }
        }
        
        // Sanity check - If the clear text message is empty, we can not display anything.
        //
        if (signMessageContext.isDoDisplayMessage() && 
            (signMessageContext.getMessageToDisplay() == null || signMessageContext.getMessageToDisplay().matches("\\s*"))) {
          
          log.warn("Sign message is empty or contains only non-visible characters [{}]", logId);
          signMessageContext.setDoDisplayMessage(false);

          if (signMessageContext.mustShow()) {
            throw new ExternalAutenticationErrorCodeException(AuthnEventIds.REQUEST_UNSUPPORTED, "No sign message to show");
          }
        }
        
        // If the SignMessage element from the signature request includes a MustShow attribute with the value true, the
        // Signature Service MUST require that the provided sign message is displayed by the Identity Provider, by
        // including a sigmessage authentication context URI.
        //
        if (signMessageContext.mustShow()) {
          AuthnContextClassContext authnContextClassContext = this.authnContextService.getAuthnContextClassContext(context);
          for (String loa : authnContextClassContext.getAuthnContextClassRefs()) {
            if (!this.isSignMessageURI(loa)) {
              log.info("SP has requested the SignMessage must be displayed, removing '{}' ... [{}]", loa, logId);
              authnContextClassContext.deleteAuthnContextClassRef(loa);
            }
          }
          if (authnContextClassContext.isEmpty()) {
            final String msg = "No valid sigmessage AuthnContext URI:s were specified in AuthnRequest";
            log.info("{} - can not proceed [{}]", msg, logId);
            throw new ExternalAutenticationErrorCodeException(AuthnEventIds.REQUEST_UNSUPPORTED, msg);
          }
        }

        // Finally, check that the DisplayEntity matches our IdP entityID.
        //
        if (signMessageContext.getSignMessage().getDisplayEntity() != null) {
          if (!this.entityID.equals(signMessageContext.getSignMessage().getDisplayEntity())) {
            final String msg = String.format("DisplayEntity (%s) of SignMessage does not match IdP entityID (%s)",
              signMessageContext.getSignMessage().getDisplayEntity(), this.entityID);
            log.info("{} - can not proceed [{}]", msg, logId);
            throw new ExternalAutenticationErrorCodeException(AuthnEventIds.REQUEST_UNSUPPORTED, msg);
          }
        }

        signMessageContext.setDoDisplayMessage(true);
      }
    }

    // Time to check SADRequest ...
    //
    SignatureActivationDataContext sadContext = this.getSadContext(context);
    if (sadContext != null) {

      if (isSignatureService) {
        // If a SADRequest is passed, a SignMessage must also be present.
        //
        if (signMessageContext == null) {
          final String msg = "Request contained SADRequest but no SignMessage was received - not allowed";
          log.info("{} - can not proceed [{}]", msg, logId);
          throw new ExternalAutenticationErrorCodeException(ExtAuthnEventIds.SWEID_BAD_REQUEST, msg);
        }
        else if (!signMessageContext.isDoDisplayMessage()) {
          // If we cannot display the SignMessage we can not issue a SAD ...
          final String msg = "SignMessage can not be displayed and SAD is requested";
          log.info("{} - can not proceed [{}]", msg, logId);
          throw new ExternalAutenticationErrorCodeException(ExtAuthnEventIds.SWEID_BAD_REQUEST, msg);
        }
        else {
          // Verify the SAD request ...
          //
          this.verifySadRequest(sadContext, context);
        }
      }
      else {
        log.warn("Requesting SP is not a signature service, but included SAPRequest extension in request, ignoring ... [{}]", logId);
        AuthenticationContext authnContext = this.getAuthenticationContext(context);
        authnContext.removeSubcontext(SignatureActivationDataContext.class);
      }
    }

  }
@ Override public void processRequest ( ProfileRequestContext < ? , ? > context ) throws ExternalAutenticationErrorCodeException { final String logId = this . getLogString ( context ) ; boolean isSignatureService = this . isSignatureServicePeer ( context ) ; SignMessageContext signMessageContext = this . getSignMessageContext ( context ) ; if ( signMessageContext == null ) { if ( isSignatureService ) { AuthnContextClassContext authnContextClassContext = this . authnContextService . getAuthnContextClassContext ( context ) ; for ( String loa : authnContextClassContext . getAuthnContextClassRefs ( ) ) { if ( this . isSignMessageURI ( loa ) ) { log . info ( "SP has requested '{}' but did not include SignMessage, removing ... [{}]" , loa , logId ) ; authnContextClassContext . deleteAuthnContextClassRef ( loa ) ; } } if ( authnContextClassContext . isEmpty ( ) ) { final String msg = "No valid AuthnContext URI:s were specified in AuthnRequest" ; log . info ( "{} - can not proceed [{}]" , msg , logId ) ; throw new ExternalAutenticationErrorCodeException ( AuthnEventIds . REQUEST_UNSUPPORTED , msg ) ; } } } else { if ( ! isSignatureService ) { log . warn ( "Requesting SP is not a signature service, but included SignMessage extension, ignoring ... [{}]" , logId ) ; AuthenticationContext authnContext = this . getAuthenticationContext ( context ) ; authnContext . removeSubcontext ( SignMessageContext . class ) ; } else { if ( signMessageContext . getSignMessage ( ) . getEncryptedMessage ( ) != null ) { try { Message cleartextMessage = this . signatureSupportKeyService . decrypt ( signMessageContext . getSignMessage ( ) ) ; log . debug ( "SignMessage was successfully decrypted [{}]" , logId ) ; signMessageContext . setClearTextMessage ( cleartextMessage ) ; } catch ( DecryptionException e ) { final String msg = String . format ( "Failed to decrypt SignMessage - %s" , e . getMessage ( ) ) ; log . error ( "{} [{}]" , msg , logId ) ; throw new ExternalAutenticationErrorCodeException ( ExtAuthnEventIds . SIGN_MESSAGE_DECRYPTION_ERROR , msg ) ; } } else { log . debug ( "SignMessage was not encrypted [{}]" , logId ) ; } if ( ! this . supportsMimeType ( signMessageContext . getMimeType ( ) ) ) { log . warn ( "IdP does not support display of SignMessage with type '{}' [{}]" , signMessageContext . getMimeType ( ) , logId ) ; signMessageContext . setDoDisplayMessage ( false ) ; if ( signMessageContext . mustShow ( ) ) { throw new ExternalAutenticationErrorCodeException ( ExtAuthnEventIds . SIGN_MESSAGE_TYPE_NOT_SUPPORTED , "Unsupported SignMessage mime type" ) ; } } if ( this . signMessagePreProcessor != null && signMessageContext . getClearTextMessage ( ) != null ) { try { String messageToDisplay = this . signMessagePreProcessor . processSignMessage ( signMessageContext . getClearTextMessage ( ) , signMessageContext . getMimeType ( ) ) ; signMessageContext . setMessageToDisplay ( messageToDisplay ) ; } catch ( SignMessageContentException e ) { log . error ( "Failed to process sign message: {} [{}]" , e . getMessage ( ) , logId ) ; if ( signMessageContext . mustShow ( ) ) { throw new ExternalAutenticationErrorCodeException ( AuthnEventIds . REQUEST_UNSUPPORTED , e . getMessage ( ) ) ; } else { signMessageContext . setDoDisplayMessage ( false ) ; } } } if ( signMessageContext . isDoDisplayMessage ( ) && ( signMessageContext . getMessageToDisplay ( ) == null || signMessageContext . getMessageToDisplay ( ) . matches ( "\\s*" ) ) ) { log . warn ( "Sign message is empty or contains only non-visible characters [{}]" , logId ) ; signMessageContext . setDoDisplayMessage ( false ) ; if ( signMessageContext . mustShow ( ) ) { throw new ExternalAutenticationErrorCodeException ( AuthnEventIds . REQUEST_UNSUPPORTED , "No sign message to show" ) ; } } if ( signMessageContext . mustShow ( ) ) { AuthnContextClassContext authnContextClassContext = this . authnContextService . getAuthnContextClassContext ( context ) ; for ( String loa : authnContextClassContext . getAuthnContextClassRefs ( ) ) { if ( ! this . isSignMessageURI ( loa ) ) { log . info ( "SP has requested the SignMessage must be displayed, removing '{}' ... [{}]" , loa , logId ) ; authnContextClassContext . deleteAuthnContextClassRef ( loa ) ; } } if ( authnContextClassContext . isEmpty ( ) ) { final String msg = "No valid sigmessage AuthnContext URI:s were specified in AuthnRequest" ; log . info ( "{} - can not proceed [{}]" , msg , logId ) ; throw new ExternalAutenticationErrorCodeException ( AuthnEventIds . REQUEST_UNSUPPORTED , msg ) ; } } if ( signMessageContext . getSignMessage ( ) . getDisplayEntity ( ) != null ) { if ( ! this . entityID . equals ( signMessageContext . getSignMessage ( ) . getDisplayEntity ( ) ) ) { final String msg = String . format ( "DisplayEntity (%s) of SignMessage does not match IdP entityID (%s)" , signMessageContext . getSignMessage ( ) . getDisplayEntity ( ) , this . entityID ) ; log . info ( "{} - can not proceed [{}]" , msg , logId ) ; throw new ExternalAutenticationErrorCodeException ( AuthnEventIds . REQUEST_UNSUPPORTED , msg ) ; } } signMessageContext . setDoDisplayMessage ( true ) ; } } SignatureActivationDataContext sadContext = this . getSadContext ( context ) ; if ( sadContext != null ) { if ( isSignatureService ) { if ( signMessageContext == null ) { final String msg = "Request contained SADRequest but no SignMessage was received - not allowed" ; log . info ( "{} - can not proceed [{}]" , msg , logId ) ; throw new ExternalAutenticationErrorCodeException ( ExtAuthnEventIds . SWEID_BAD_REQUEST , msg ) ; } else if ( ! signMessageContext . isDoDisplayMessage ( ) ) { final String msg = "SignMessage can not be displayed and SAD is requested" ; log . info ( "{} - can not proceed [{}]" , msg , logId ) ; throw new ExternalAutenticationErrorCodeException ( ExtAuthnEventIds . SWEID_BAD_REQUEST , msg ) ; } else { this . verifySadRequest ( sadContext , context ) ; } } else { log . warn ( "Requesting SP is not a signature service, but included SAPRequest extension in request, ignoring ... [{}]" , logId ) ; AuthenticationContext authnContext = this . getAuthenticationContext ( context ) ; authnContext . removeSubcontext ( SignatureActivationDataContext . class ) ; } } }
If a {@code SignMessage} exists the method will decrypt it (if needed).