no.difi.sdp.client2.internal.Wss4jClientSecurityExceptionMapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sikker-digital-post-klient-java Show documentation
Show all versions of sikker-digital-post-klient-java Show documentation
Klient for sending av sikker digital post fra offentlige virksomheter.
package no.difi.sdp.client2.internal;
import no.difi.sdp.client2.domain.Noekkelpar;
import no.difi.sdp.client2.domain.exceptions.NoekkelException;
import no.difi.sdp.client2.domain.exceptions.SendException;
import no.difi.sdp.client2.domain.exceptions.UgyldigTidsstempelException;
import no.digipost.api.exceptions.MessageSenderEbmsErrorException;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointExceptionResolver;
import org.springframework.ws.soap.security.wss4j2.Wss4jSecurityValidationException;
import static no.difi.sdp.client2.domain.exceptions.SendException.AntattSkyldig.UKJENT;
/**
* Even if this class implements the {@see org.springframework.ws.server.EndpointExceptionResolver}, this implementation is injected into our {@see no.digipost.api.interceptors.WsSecurityInterceptor},
* which is a client interceptor in the context of this library. An {@see org.springframework.ws.server.EndpointExceptionResolver} is supposed to be used by the message dispatcher on the server side.
* This is why this resolver is used like an exception mapper instead of an exception resolver, and is just a way of dealing with a broken framework. When looking at how exceptions are handled by other
* client interceptors, for instance {@see org.springframework.ws.client.support.interceptor.PayloadValidatingInterceptor} it is clear that the exceptions are supposed to be thrown in client interceptors
* in order to handle control flow.
*/
class Wss4jClientSecurityExceptionMapper implements EndpointExceptionResolver {
/**
* Maps undlerlying security exceptions into proper, human readable exceptions.
*
* @param messageContext
* @param o
* @param e
* @return Will always throw exceptions, so there will never be a return value of true/false. This is contradictory to the interface documentation of {@see EndpointExceptionResolver}
*/
@Override
public boolean resolveException(MessageContext messageContext, Object o, Exception e) {
if (e.getMessage() != null) {
boolean isPossiblyIncorrectLocalTimeException =
(e instanceof Wss4jSecurityValidationException || e instanceof MessageSenderEbmsErrorException)
&& e.getMessage().contains("Invalid timestamp: The message timestamp is out of range");
if (isPossiblyIncorrectLocalTimeException) {
throw new UgyldigTidsstempelException("Ugyldig timestamp i sendt melding. Dette kan skyldes at maskinen som klienten kjører på ikke har stilt klokken korrekt.", e);
}
boolean isCouldNotFindTrustedCertificatesException = (e instanceof Wss4jSecurityValidationException && e.getMessage().contains("No trusted certs found"));
if (isCouldNotFindTrustedCertificatesException) {
throw new NoekkelException("Klarte ikke å verifisere signatur på responsen. Dette kan skyldes at det tiltrodde rotsertifikatet for Meldingsformidler mangler i keystore eller trust store. " +
"Bruk overload for " + Noekkelpar.class.getSimpleName() + " som bruker klientens innebygde sertifikater for trust store eller legg inn mellomliggende sertifikat og rotsertifikat " +
"til Buypass og Commfides i trust store.");
}
}
throw new SendException("Under mapping av exception skjedde en feil som ikke kunne håndteres.", UKJENT, e);
}
}