2017-10-17 80 views
0

SOAP 서비스에 대한 "클라이언트 인증서"인증을 수행 할 수 있어야합니다.Spring WS 클라이언트 - 서버 및 클라이언트 인증서로 인증

저는 스프링 WS를 사용하고 있습니다. 나는 my.key, myCA.pemmyClient.crt입니다.

public TheResponse doIt(TheRequest request) { 
    log.info("Sending request..."); 
    try { 
    InputStream is = new FileInputStream(new File("src/main/resources/keystore.jks")); 
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    keyStore.load(is, "keystore!passwd".toCharArray()); 
    is.close(); 
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    keyManagerFactory.init(keyStore, keyStorePassword.toCharArray()); 

    InputStream is1 = new FileInputStream(new File("src/main/resources/truststore.jks")); 
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    trustStore.load(is1, "truststore!passwd".toCharArray()); 
    is1.close(); 
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    trustManagerFactory.init(trustStore); 

    HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender(); 
    messageSender.setKeyManagers(keyManagerFactory.getKeyManagers()); 
    messageSender.setTrustManagers(trustManagerFactory.getTrustManagers()); 
    setMessageSender(messageSender); 

    return (TheResponse) getWebServiceTemplate().marshalSendAndReceive(request, 
     new SoapActionCallback("https://domain/tld/icc/SomePathDownTheLine")); 
    } catch (Throwable e) { 
    log.error("Sh*t didn't work due to:", e); 
    throw new GatewayConnectionException(String.format("Unexpected error while sending request [%s]", e.getMessage())); 
    } 
} 

이 내가 신뢰를 짓고 있어요 방법은 다음과 같습니다

이 코드의 내 관련 자바 조각 (나는 여전히 지저분한 알고하지만 난 그냥 처음으로 일하러 가야 을 시도하고있다)이다 - 그리고 키 - 저장 :

# KeyStore 
$ openssl pkcs12 -export -in myClient.crt -inkey my.key -out keystore.p12 -name my_key -CAfile myCA.pem -caname root 

$ keytool -importkeystore -deststorepass keystore!passwd -destkeypass keystore!passwd -destkeystore keystore.jks \ 
    -srckeystore keystore.p12 -srcstoretype PKCS12 -srcstorepass keystore!passwd -alias my_key 

# Trustore (using truststore!passwd) 
$ keytool -import -trustcacerts -alias my_ca -file myCA.pem -keystore truststore.jks 

$ keytool -import -trustcacerts -alias my_cc -file myClient.crt -keystore truststore.jks 

... 그리고 이러한 검증 단계는 다음과 같습니다

$ keytool -list -keystore keystore.jks -storepass ******** 

Keystore type: JKS 
Keystore provider: SUN 

Your keystore contains 1 entry 

my_key, Oct 17, 2017, PrivateKeyEntry, 
Certificate fingerprint (SHA1): 1A:9D:6A:65:. . .:E6:C1:90 

$ keytool -list -keystore truststore.jks -storepass ******** 

Keystore type: JKS 
Keystore provider: SUN 

Your keystore contains 2 entries 

my_cc, Oct 17, 2017, trustedCertEntry, 
Certificate fingerprint (SHA1): 1A:9D:6A:65:. . .:E6:C1:90 
my_ca, Oct 17, 2017, trustedCertEntry, 
Certificate fingerprint (SHA1): 36:82:F7:AB:. . .:70:B2:6C 

...하지만 여전히 SOAP 동작을 요청할 때마다 HTTP 401 (Unauthorized) (org.springframework.ws.client.WebServiceTransportException: Unauthorized [401])이 반환됩니다.

실마리가 있습니까? 그건 그렇고, 난 꽤 많이 따라 가이드 this. 나는 SSL 인증서와 그 모든 것들에 익숙하지 않다.


UPDATE

SSL 핸드 셰이크가 제대로 작동합니다. -Djavax.net.debug=all VM 옵션을 설정하여 작동 방식을 확인할 수 있습니다. 현재이 보안 상태에 관계없이 서버에는 사용자 이름과 암호가 필요하다는 것이 있습니다.

답변

0

이것은 모두 정상입니다. 궁극적으로 서비스가 Basic auth을 필요로하고 그것을 보내지 않았기 때문에 HTTP 401 (Unauthorized)의 이유가있었습니다.

모든 키 스토어 및 트러스트 스토어 세대가 완벽합니다. 이것은 (스프링 웹 서비스를 사용하여) "최종"솔루션입니다 :

// 
    // Spring Config 

    // Inject messageSender() into a WebServiceTemplate or, 
    // Have a class that extends from WebServiceGatewaySupport 

    @Bean 
    public HttpsUrlConnectionMessageSender messageSender() throws Exception { 
    HttpsUrlConnectionMessageSender messageSender = new BasicAuthHttpsConnectionMessageSender(username, password); 
    messageSender.setTrustManagers(trustManagersFactoryBean().getObject()); 
    messageSender.setKeyManagers(keyManagersFactoryBean().getObject()); 
    return messageSender; 
    } 

    @Bean 
    public TrustManagersFactoryBean trustManagersFactoryBean() { 
    TrustManagersFactoryBean trustManagersFactoryBean = new TrustManagersFactoryBean(); 
    trustManagersFactoryBean.setKeyStore(trustStore().getObject()); 
    return trustManagersFactoryBean; 
    } 

    @Bean 
    public KeyManagersFactoryBean keyManagersFactoryBean() { 
    KeyManagersFactoryBean keyManagersFactoryBean = new KeyManagersFactoryBean(); 
    keyManagersFactoryBean.setKeyStore(keyStore().getObject()); 
    keyManagersFactoryBean.setPassword(keyStorePassword); 
    return keyManagersFactoryBean; 
    } 

    @Bean 
    public KeyStoreFactoryBean trustStore() { 
    KeyStoreFactoryBean keyStoreFactoryBean = new KeyStoreFactoryBean(); 
    keyStoreFactoryBean.setLocation(new ClassPathResource("truststore.jks")); // Located in src/main/resources 
    keyStoreFactoryBean.setPassword(trustStorePassword); 
    return keyStoreFactoryBean; 
    } 

    @Bean 
    public KeyStoreFactoryBean keyStore() { 
    KeyStoreFactoryBean keyStoreFactoryBean = new KeyStoreFactoryBean(); 
    keyStoreFactoryBean.setLocation(new ClassPathResource("keystore.jks")); 
    keyStoreFactoryBean.setPassword(keyStorePassword); 
    return keyStoreFactoryBean; 
    } 

// You might need org.springframework.ws:spring-ws-support in order to 
// have HttpsUrlConnectionMessageSender 
public final class BasicAuthHttpsConnectionMessageSender extends HttpsUrlConnectionMessageSender { 
    private String b64Creds; 

    public BasicAuthHttpsConnectionMessageSender(String username, String password) { 
    b64Creds = Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); 
    } 

    @Override 
    protected void prepareConnection(HttpURLConnection connection) throws IOException { 
    connection.setRequestProperty(HttpHeaders.AUTHORIZATION, String.format("Basic %s", b64Creds)); 
    super.prepareConnection(connection); 
    } 
} 

one도 참조하십시오 - 나 자신에 의해 요청이 수 O :

희망 미래에 누군가를 도우십시오. 모든 것을 정리하는 데는 시간이 걸렸습니다.