Closed phax closed 1 year ago
@sopgreg what you can do today already, is to query the signature and decryption state in your code via the IAS4MessageState
:
aState.isSoapSignatureChecked ()
returns true
if the message was signedaState.isSoapDecrypted()
returns true
if the message was decryptedThanks @phax! I put this in our IAS4ServletMessageProcessorSPI#processAS4UserMessage
. Would that be a "correct" implementation where the sender receives the proper reason for failed processing of his message?
if (!messageState.isSoapDecrypted()) {
processingErrorMessages.add(EEbmsError.EBMS_FAILED_DECRYPTION.getAsEbms3Error(Locale.getDefault(), null));
String errorMessage = String.format("Incoming AS4 message from %s to %s was not encrypted",
initiatorID, responderID);
LOGGER.error(errorMessage);
return AS4MessageProcessorResult.createFailure(errorMessage);
}
if (!messageState.isSoapSignatureChecked()) {
processingErrorMessages.add(EEbmsError.EBMS_FAILED_AUTHENTICATION.getAsEbms3Error(Locale.getDefault(), null));
String errorMessage = String.format("Incoming AS4 message from %s to %s had no signature or signature verification failed",
initiatorID, responderID);
LOGGER.error(errorMessage);
return AS4MessageProcessorResult.createFailure(errorMessage);
}
The usage of both the processingErrorMessages
and the error message in createFailure
seems a bit redundant to me. Is there a variant you would recommend?
Yes that looks good. I am working on an additional "profile requirement" to make that check on a deeper level automatically as you suggested.
Additionally your comment on AS4MessageProcessorResult.createFailure(errorMessage);
is totally right. As this messgae is never used, it will be also be deprecated in the upcoming release. processingErrorMessages
is the way to go
Regarding the error code I would vouch for EBMS:0103:
Regarding the error code I would vouch for EBMS:0103:
EBMS:0103 sounds fine, thanks.
Additionally your comment on AS4MessageProcessorResult.createFailure(errorMessage); is totally right. As this messgae is never used, it will be also be deprecated in the upcoming release. processingErrorMessages is the way to go
I actually do like the error message in AS4MessageProcessorResult.createFailure(errorMessage)
as it is automatically mapped to an Ebms error with a correct refToMessageInError
in AS4RequestHandler
:
There is no easy way to get that refToMessageInError
in the SPI, is there? Apart from copying the same code from AS4RequestHandler
:
final String sMessageID = bIsUserMessage ? aEbmsUserMessage.getMessageInfo ().getMessageId () : aEbmsSignalMessage
.getMessageInfo ()
.getMessageId ();
EDIT: seems that messageState.getMessage()
seems to be the way to go.
Yes that looks good. I am working on an additional "profile requirement" to make that check on a deeper level automatically as you suggested.
Great if this can be handled on a deeper level, then we could remove our code in the SPI again later.
To access the "RefToMessageID" please use
String IAS4MessageState.getRefToMessageID ();
The problem with the createFailure(String)
is, that it allows only 1 error message. In some cases multiple error messages make sense. And as I consider it bad style to offer the same functionality in 2 different ways, I opt for the generic one using processingErrorMessages.add (...)
@sopgreg I thought this through a little more and I stumbled upon an issue we haven't considered previously: when making the decision in the profile, it means that this applies to ALL messages. As Receipts may not be encrypted and Error Messages may not even be signed, I decided to remove this feature from the release. Having the check in your "User Message Receiption" code is the safest atm.
It would be an option to configure this requirement in the PMode on a per message type basis (UserMessage, PullRequest, Error, Receipt), but that looks like too much overhead. Any thoughts from you on this?
I also can't image all possible combinations right now when and under which circumstances a response message may or may not be signed/encrypted. At least for BDEW, PullRequests are out of scope. So any UserMessage and all signal that do not contain errors should be technically signed and encrypted. Is this assumption correct or did I miss some edge cases?
To access the "RefToMessageID" please use String IAS4MessageState.getRefToMessageID ();
In the code you committed today you used #getMessageId
. Was this on purpose or is getRefToMessageId
the correct one?
Okay, thanks for your understanding.
getMessageId()
is used to get the message ID of the currently processed message.
getRefToMessageId()
is used in Receipt or Error Messages to refence the MessageId
of the source message. So the answer message referring to the source message.
When dealing with the "source user message" getMessageId()
is what you are looking for
Discussed in https://github.com/phax/phase4/discussions/161