2014-01-23 5 views
1

Я пытаюсь загрузить файл в веб-службу, которая работает через SSL с использованием HttpBuilder. Я делаю это из файла сборки Gradle, но я не думаю, что это действительно имеет значение. Веб-сервис является частью приложения Grails, но опять же, не думайте, что это важно.Загрузка файла с использованием HttpBuilder по SSL

Приложение grails работает через SSL локально, используя сертификат, созданный grails, когда вы говорите ему, чтобы он работал по https. Мой код, который работает локально выглядит следующим образом:

def http = new groovyx.net.http.HTTPBuilder('https://localhost:8443/') 

//=== SSL UNSECURE CERTIFICATE === 
def sslContext = SSLContext.getInstance("SSL") 
sslContext.init(null, [ new X509TrustManager() { 
    public X509Certificate[] getAcceptedIssuers() {null } 
    public void checkClientTrusted(X509Certificate[] certs, String authType) { } 
    public void checkServerTrusted(X509Certificate[] certs, String authType) { } 
} ] as TrustManager[], new SecureRandom()) 
def sf = new SSLSocketFactory(sslContext) 
def httpsScheme = new Scheme("https", sf, 8443) 
http.client.connectionManager.schemeRegistry.register(httpsScheme) 

http.request(groovyx.net.http.Method.POST, groovyx.net.http.ContentType.JSON) { req -> 
    uri.path = '/a/admin/runtime/upload' 
    uri.query = [ username: "username", password: "password", version: version] 
    requestContentType = 'multipart/form-data' 
    org.apache.http.entity.mime.MultipartEntity entity = new org.apache.http.entity.mime.MultipartEntity() 
    def file = new File("file.zip") 
    entity.addPart("runtimeFile", new org.apache.http.entity.mime.content.ByteArrayBody(file.getBytes(), 'file.zip')) 
    req.entity = entity 
} 

Все, что мусор на вершине какой-то код, который я нашел, что позволяет HttpBuilder работать с самоподписывающимися сертификатами. И это на самом деле работает локально. Документы HttpBuilder говорят, что большую часть времени SSL должен «просто работать». Так что мой код делает это через SSL с законной закупленной сертификацией следующим образом:

def http = new groovyx.net.http.HTTPBuilder('https://www.realserver.com/') 

http.request(groovyx.net.http.Method.POST, groovyx.net.http.ContentType.JSON) { req -> 
    uri.path = '/a/admin/runtime/upload' 
    uri.query = [ username: "username", password: "password" ] 
    requestContentType = 'multipart/form-data' 
    org.apache.http.entity.mime.MultipartEntity entity = new org.apache.http.entity.mime.MultipartEntity() 
    def file = new File("file.zip") 
    entity.addPart("runtimeFile", new org.apache.http.entity.mime.content.ByteArrayBody(file.getBytes(), 'file.zip')) 
    req.entity = entity 
} 

Когда я запускаю это я получаю следующее сообщение об ошибке:

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 

Любые советы и предложения будут оценены.

ответ

0

Возможно, это связано с тем, что служба использует самозаверяющий сертификат для HTTPS. Чтобы правильно взаимодействовать с ним, вы должны импортировать его в файл cacerts вашей JRE, используя keytool. Пример команды выглядит так:

keytool -import -alias serviceCertificate -file ServiceSelfSignedCertificate.cer -keystore {path/to/jre/lib/security/cacerts} 
+0

Это не самоподписанный сертификат. Как я уже сказал в своем вопросе, «это по SSL с законно купленной сертификацией». – Gregg

+0

Однако корневой сертификат этого сертификата может быть не в 'cacerts', поэтому вам нужно его импортировать. –

Смежные вопросы