Как использовать самозаверяющий сертификат в Java-клиенте Axis2? - PullRequest
3 голосов
/ 25 июня 2011

Я сгенерировал код, используя org.codehaus.mojo axistools-maven-plugin плагин версии 1.4.Я пытаюсь подключиться к веб-сервису через https.Я установил сертификат сервера в jssecacerts и скопировал это хранилище ключей в папку /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/.Так что это означает, что у меня есть сертификат сервера в хранилище ключей клиента.Я также импортировал закрытый ключ сервера и сертификат в хранилище ключей kestore.ImportKey.Я думаю, мне придется использовать это в качестве хранилища доверия.Теперь, как мне соединить все это вместе в Java-клиенте?Я использую автоматически созданную заглушку на стороне клиента.Я попытался использовать следующее, но не работает.

System.setProperty("javax.net.ssl.trustStore","certs/keystore.ImportKey");
System.setProperty("javax.net.ssl.trustStorePassword", "importkey"); 

Я получаю следующее исключение.

faultString: javax.net.ssl.SSLHandshakeException: 
    sun.security.validator.ValidatorException: 
PKIX path building failed: 
    sun.security.provider.certpath.SunCertPathBuilderException:
     unable to find valid certification path to requested target

Сертификаты действительны, поскольку я использую одни и те же сертификаты через HTTPS-клиент для одного и того же хоста.Кроме того, я смог увидеть успешный запрос curl для использования тех же сертификатов.На самом деле я не уверен, как написать Java-клиент Axis2 поверх https, используя самозаверяющий сертификат сервера.Может ли кто-нибудь указать мне шаг за шагом пример.

Ответы [ 2 ]

2 голосов
/ 26 июня 2011

Спасибо @ Jcs

Так я решил проблему.Когда я попытался открыть URL веб-сервиса в браузере, он запросил сертификат клиента.Это означает, что, поскольку я уже импортировал сертификат сервера в jssecacert в jvm, мой клиент пропустил сертификат клиента.Таким образом, вместо установки свойств javax.net.ssl.trustStore и javax.net.ssl.trustStorePassword я устанавливаю свойства javax.net.ssl.keyStore и javax.net.ssl.keyStorePassword, и все работает нормально.Я пропустил до того, что закрытый ключ и сертификат были импортированы в хранилище ключей.ImportKey - это, в основном, идентификация клиента, которую я давно получил от того, кто сказал, что это сертификаты сервера.Это вводило меня в заблуждение.Итак, позвольте мне обобщить решение, если кто-то его ищет.

  1. Загрузите сертификат сервера и импортируйте его в JVM cacerts или jssecacerts по системному пути.Я использовал этот пост .

  2. Открыть URL-адрес веб-службы в браузере и, если он запрашивает сертификат клиента, это означает, что сервер настроен на получение сертификата от клиента.В случае самоподписанного сертификата у вас уже должен быть самоподписанный сертификат с сервера.Импортируйте их в хранилище ключей и задайте системные свойства для хранилища ключей, а не хранилища доверенных сертификатов, прежде чем фактически выполнять вызов веб-службы, как показано ниже.Это связано с тем, что вы уже импортировали сертификат сервера в доверенное хранилище клиента (cacerts).

Код:

MySoap12Stub stub = (MySoap12Stub) new MyLocator().getMySoap12(new java.net.URL(WSUrl));

System.setProperty("javax.net.ssl.keyStore", "certs/keystoreQA.Importkey");
System.setProperty("javax.net.ssl.keyStorePassword", "importkey");

Кроме того, в моем случае серверожидание токена пользователя и пароля, установленных в заголовках SOAP.Вот как я установил это в заголовки SOAP:

((Stub) stub).setHeader(HeaderHandler.getSecurityHeader(User, password));

public class HeaderHandler {

    public static SOAPHeaderElement getSecurityHeader(String user,String password) throws Exception {
        SOAPHeaderElement wsseSecurity = new SOAPHeaderElement(new PrefixedQName(
            "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
            "Security", "wsse"));
        wsseSecurity.setActor(null);
        wsseSecurity.setMustUnderstand(true);

        SOAPElement usernameToken = wsseSecurity.addChildElement("UsernameToken", "wsse");
        usernameToken.setAttribute("xmlns:wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
        SOAPElement username = usernameToken.addChildElement("Username", "wsse");
        username.addTextNode(user);

        SOAPElement password = usernameToken.addChildElement("Password", "wsse");
        password.setAttribute("Type","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
        password.addTextNode(password);
        return wsseSecurity;
    }
} 

Я надеюсь, что это подробно объясняет, как использовать самозаверяющие сертификаты и токен пользователя WSSE и пароль в клиенте axis2, вызывающем веб-службы через https, используя usertoken и пароль.

Ура!хорошо идти сейчас.

2 голосов
/ 25 июня 2011

На стороне клиента вам не нужен закрытый ключ сертификата, чтобы доверять серверу.Поскольку вы указали в своем вопросе, что вы импортировали сертификат и ключ в keystore.ImportKey, я думаю, что они были импортированы как PrivateKeyEntry (вы можете проверить с помощью keytool тип записей в хранилище ключей).

Однако, если вы хотите использовать сертификат в качестве доверительного якоря, вы должны импортировать сертификат как TrustedCertificateEntry.Это может быть достигнуто с помощью keytool:

keytool -importcert -trustcacerts -alias myTrustAnchor -file /path/to/cert.crt -keystore /path/to/keystore

Затем вы можете настроить хранилище доверенных сертификатов в вашем приложении:

System.setProperty("javax.net.ssl.trustStore","/path/to/keystore");
...