如何为Groovy/Java的RESTClient配置mTLS的SSLContext
解决RESTClient配置mTLS连接的问题
关键修改点
- 修正SSLContext初始化参数:原代码中
sc.init的第二个参数直接传入了trustManagerFactory对象,这是错误的,需要传入trustManagerFactory.getTrustManagers()获取TrustManager数组。 - 配置自定义HttpClient到RESTClient:RESTClient底层依赖Apache HttpClient,需要将我们构建的带mTLS配置的HttpClient赋值给RESTClient的
client属性。
修改后的完整代码
... def mymTLSservice = "https://my-token-service.example.com" // Load custom my TrustStore and KeyStore def pathToKeyStore = "/path/to/keystore.jceks" def pathToTrustStore = "/path/to/truststore" def keyStorePW = "myKeyStorePW" def trustStorePW = "myTrustStorePW" final char[] pwdKeyStore = keyStorePW.toCharArray() final char[] pwdTrustStore = trustStorePW.toCharArray() String keyAlias = "my-mTls-cert-alias" // If you have more than one key String storeType = "JCEKS" FileInputStream keyStoreInputStream = new FileInputStream(pathToKeyStore) FileInputStream trustStoreInputStream = new FileInputStream(pathToTrustStore) KeyStore ks = KeyStore.getInstance(storeType) ks.load(keyStoreInputStream, pwdKeyStore) KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()) trustStore.load(trustStoreInputStream, pwdTrustStore) Key mTlsPrivateKey = ks.getKey(keyAlias, pwdKeyStore) Certificate[] mTlsChain = ks.getCertificateChain(keyAlias) KeyStore mtlsKeyStore = KeyStore.getInstance("jks") mtlsKeyStore.load(null, null) mtlsKeyStore.setKeyEntry(keyAlias, mTlsPrivateKey, pwdKeyStore, mTlsChain) KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509") keyManagerFactory.init(mtlsKeyStore, pwdKeyStore) TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trustStore); // Create SSLContext - 修正第二个参数 SSLContext sc = SSLContext.getInstance("TLS"); sc.init( keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), // 改为获取TrustManager数组 new java.security.SecureRandom()); SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(sc) // 构建自定义HttpClient并赋值给RESTClient def httpClient = org.apache.http.impl.client.HttpClients.custom() .setSSLSocketFactory(sf) .build() def http = new RESTClient(mymTLSservice) http.client = httpClient // 关键:设置自定义HttpClient http.auth.basic 'user', 'password' http.handler.failure = { resp -> println "Failure: ${resp.statusLine}" } // Trying request def access_token = '' try{ def resp = http.get( path : "/v2/token" ) { resp, json -> access_token = json println "access_token" } println resp } catch(HttpResponseException e) { def r = e.response println("Success: $r.success") println("Status: $r.status") println("Reason: $r.statusLine.reasonPhrase") println("Could not retrieve an access token from token provider!") }
补充说明
- 确保依赖中包含Apache HttpClient的相关包(Groovy RESTClient通常已经依赖,但如果是单独引入需要确认)。
- 如果需要更精细的SSL配置(比如指定TLS版本、禁用不安全协议等),可以在创建
SSLConnectionSocketFactory时添加参数,例如:
SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory( sc, new String[]{"TLSv1.2", "TLSv1.3"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier() )
内容的提问来源于stack exchange,提问作者allinformatix
相关产品推荐
相关产品推荐

