Ich rufe den HTTPS SOAP Webdienst über Java Code auf. Ich habe bereits ein selbstsigniertes Zertifikat in den jre cacerts Keystore importiert. Jetzt erhalte ich:
com.Sun.xml.internal.ws.com.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: Java.security.cert.CertificateException: No subject alternative names present
Der Hostname der Service-URL stimmt nicht mit dem des in cert angegebenen CN überein. Ich habe über eine Problemumgehung beim Definieren eines benutzerdefinierten Hostnamen-Verifizierers gelesen hier . Aber ich kann nicht machen, wo ich die Problemumgehung in meinem Code implementieren sollte.
public SOAPMessage invokeWS(WSBean bean) throws Exception {
SOAPMessage response=null;
try{
/** Create a service and add at least one port to it. **/
String targetNameSpace = bean.getTargetNameSpace();
String endpointUrl = bean.getEndpointUrl();
QName serviceName = new QName(targetNameSpace, bean.getServiceName());
QName portName = new QName(targetNameSpace, bean.getPortName());
String SOAPAction = bean.getSOAPAction();
HashMap<String, String> map = bean.getParameters();
Service service = Service.create(serviceName);
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointUrl);
/** Create a Dispatch instance from a service. **/
Dispatch dispatch = service.createDispatch(portName, SOAPMessage.class,
Service.Mode.MESSAGE);
// The soapActionUri is set here. otherwise we get a error on .net based
// services.
dispatch.getRequestContext().put(Dispatch.SOAPACTION_USE_PROPERTY,
new Boolean(true));
dispatch.getRequestContext().put(Dispatch.SOAPACTION_URI_PROPERTY,
SOAPAction);
/** Create SOAPMessage request. **/
// compose a request message
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
// Create objects for the message parts
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPBody body = envelope.getBody();
SOAPElement bodyElement = body.addChildElement(bean.getInputMethod(),
bean.getPrefix(), bean.getTargetNameSpace());
...more code to form soap body goes here
// Print request
message.writeTo(System.out);
// Save the message
message.saveChanges();
response = (SOAPMessage)dispatch.invoke(message);
}
catch (Exception e) {
log.error("Error in invokeSiebelWS :"+e);
}
return response;
}
Bitte ignorieren Sie den WSBean-Parameter, da die Namespaces und andere wsdl-Attribute von dieser Bean stammen. Und wenn diese Ausnahme mit einigen verschiedenen Problemumgehungen behoben werden kann, schlagen pls vor.
Danke, Bruno, dass du mir den gebräuchlichen Namen und den alternativen Antragstellernamen mitgeteilt hast. Wie wir herausgefunden haben, wurde das Zertifikat mit CN mit dem DNS-Namen des Netzwerks generiert und um die Wiederherstellung eines neuen Zertifikats mit dem Eintrag für den alternativen Antragstellernamen, d. H. San = ip: 10.0.0.1, gebeten. Welches ist die tatsächliche Lösung.
Es ist uns jedoch gelungen, eine Problemumgehung zu finden, mit der wir in der Entwicklungsphase arbeiten können. Fügen Sie einfach einen statischen Block in die Klasse ein, aus der die SSL-Verbindung hergestellt wird.
static {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
public boolean verify(String hostname, SSLSession session)
{
// ip address of the service URL(like.23.28.244.244)
if (hostname.equals("23.28.244.244"))
return true;
return false;
}
});
}
Wenn Sie zufällig Java 8 verwenden, gibt es eine viel schnellere Möglichkeit, das gleiche Ergebnis zu erzielen:
static {
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> hostname.equals("127.0.0.1"));
}
Im Gegensatz zu einigen Browsern folgt Java) der HTTPS-Spezifikation, wenn es um die Überprüfung der Serveridentität (RFC 2818, Abschnitt 3.1) und IP-Adressen geht.
Bei Verwendung eines Hostnamens kann auf den allgemeinen Namen im Antragstellernamen des Serverzertifikats zurückgegriffen werden, anstatt den alternativen Antragstellernamen zu verwenden.
Bei Verwendung einer IP-Adresse muss im Zertifikat ein Eintrag für einen alternativen Antragstellernamen (vom Typ IP-Adresse, nicht DNS-Name) vorhanden sein.
Weitere Informationen zur Spezifikation und zum Generieren eines solchen Zertifikats finden Sie in diese Antwort .