Java笔记-基于Spring Boot的SOAP双向SSL认证及WS-Security
這里服務端開放了簡單的SOAP的API,但是想獲取數據時需要雙向SSL以及WS-Security簽名。
其中對應的xsd文件如下:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://spring.io/guides/gs-producing-web-service"targetNamespace="http://spring.io/guides/gs-producing-web-service" elementFormDefault="qualified"><xs:element name="getCountryRequest"><xs:complexType><xs:sequence><xs:element name="name" type="xs:string"/></xs:sequence></xs:complexType></xs:element><xs:element name="getCountryResponse"><xs:complexType><xs:sequence><xs:element name="country" type="tns:country"/></xs:sequence></xs:complexType></xs:element><xs:complexType name="country"><xs:sequence><xs:element name="name" type="xs:string"/><xs:element name="population" type="xs:int"/><xs:element name="capital" type="xs:string"/><xs:element name="currency" type="tns:currency"/></xs:sequence></xs:complexType><xs:simpleType name="currency"><xs:restriction base="xs:string"><xs:enumeration value="GBP"/><xs:enumeration value="EUR"/><xs:enumeration value="PLN"/></xs:restriction></xs:simpleType> </xs:schema>對應的Maven如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.16.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>wsdl4j</groupId><artifactId>wsdl4j</artifactId><version>1.6.1</version></dependency><dependency><groupId>org.springframework.ws</groupId><artifactId>spring-ws-core</artifactId><version>3.0.8.RELEASE</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>org.codehaus.mojo</groupId><artifactId>jaxb2-maven-plugin</artifactId><version>2.5.0</version><executions><execution><id>xjc</id><goals><goal>xjc</goal></goals></execution></executions><configuration><sources><source>${project.basedir}/src/main/resources/countries.xsd</source></sources></configuration></plugin></plugins></build></project>將源碼跑起來(文章最后有源碼的打包下載地址)
從中可以看到,HTTPS以及開啟
這里使用SoapUI來測試,獲取其wsdl
會提示如下錯誤
下面將證書掛上!
完成后測試下:
可以看到連接成功,獲取到了wsdl
?
客戶端的配置
客戶端中配置主要在SoapConfiguration.java中,首先是配置SSL雙向認證:
private static final Resource KEYSTORE_LOCATION = new ClassPathResource("client.jks"); private static final String KEYSTORE_PASSWORD = "keystore"; ...@Bean Jaxb2Marshaller marshaller() {Jaxb2Marshaller marshaller = new Jaxb2Marshaller();marshaller.setContextPath("io.spring.guides.gs_producing_web_service");return marshaller; }@Bean KeyStoreFactoryBean keyStore() {KeyStoreFactoryBean factoryBean = new KeyStoreFactoryBean();factoryBean.setLocation(KEYSTORE_LOCATION);factoryBean.setPassword(KEYSTORE_PASSWORD);return factoryBean; }@Bean TrustManagersFactoryBean trustManagers(KeyStoreFactoryBean keyStore) {TrustManagersFactoryBean factoryBean = new TrustManagersFactoryBean();factoryBean.setKeyStore(keyStore.getObject());return factoryBean; }@Bean HttpsUrlConnectionMessageSender messageSender(KeyStoreFactoryBean keyStore,TrustManagersFactoryBean trustManagers ) throws Exception {HttpsUrlConnectionMessageSender sender = new HttpsUrlConnectionMessageSender();KeyManagersFactoryBean keyManagersFactoryBean = new KeyManagersFactoryBean();keyManagersFactoryBean.setKeyStore(keyStore.getObject());keyManagersFactoryBean.setPassword(KEYSTORE_PASSWORD);keyManagersFactoryBean.afterPropertiesSet();sender.setKeyManagers(keyManagersFactoryBean.getObject());sender.setTrustManagers(trustManagers.getObject());return sender; }雙向SSL認證配置同樣也需要在服務端進行設置。在高度安全的環境中客戶端都需要有自己的證書,在與服務器通信之前都需要驗證這些證書合不合法。
客戶端的keystore存放的路徑為:src/mian/resources/client.jks。這個jks中包含了客戶端的私鑰和公鑰。使用spring-ws-security配置代替HttpsUrlConnectionMessageSender,使用這種方式可以實現SOAP的雙向SSL認證。
下面是配置WS-Security:
@Bean CryptoFactoryBean cryptoFactoryBean() throws IOException {CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();cryptoFactoryBean.setKeyStoreLocation(KEYSTORE_LOCATION);cryptoFactoryBean.setKeyStorePassword(KEYSTORE_PASSWORD);return cryptoFactoryBean; }@Bean Wss4jSecurityInterceptor securityInterceptor(CryptoFactoryBean cryptoFactoryBean) throws Exception {Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();securityInterceptor.setSecurementActions("Signature");securityInterceptor.setSecurementUsername(KEY_ALIAS);securityInterceptor.setSecurementPassword(KEYSTORE_PASSWORD);securityInterceptor.setSecurementSignatureKeyIdentifier("DirectReference");securityInterceptor.setSecurementSignatureAlgorithm(WSS4JConstants.RSA_SHA1);securityInterceptor.setSecurementSignatureDigestAlgorithm(WSS4JConstants.SHA1);securityInterceptor.setSecurementSignatureCrypto(cryptoFactoryBean.getObject());return securityInterceptor; }這里需要為WSSJ4提供客戶端的keystore及password。配置SecurityInterceptor,這個攔截器將每個SOAP消息都帶上簽名。
最后在GetCountryReponseClient中使用雙向SSL及WS-Security:
@Bean CountryClient countryClient(Jaxb2Marshaller marshaller,HttpsUrlConnectionMessageSender messageSender,Wss4jSecurityInterceptor securityInterceptor ) {CountryClient countryClient = new CountryClient();countryClient.setInterceptors(new ClientInterceptor[]{securityInterceptor});countryClient.setMessageSender(messageSender);countryClient.setMarshaller(marshaller);countryClient.setUnmarshaller(marshaller);return countryClient; }下面是測試下客戶端,看看連接是否正常以及能否調用服務:
@SpringBootTest public class CountryClientIntegrationTest {@AutowiredCountryClient countryClient;@Testvoid shouldDownloadCountry() {// givenString countryName = "Poland";// whenCountry country = countryClient.getCountry(countryName).getCountry();// thenCountry expectedCountry = new Country();expectedCountry.setName("Poland");expectedCountry.setCapital("Warsaw");expectedCountry.setCurrency(Currency.PLN);expectedCountry.setPopulation(38186860);assertThat(country.getName()).isEqualTo("Poland");assertThat(country.getCapital()).isEqualTo("Warsaw");assertThat(country.getCurrency()).isEqualTo(Currency.PLN);assertThat(country.getPopulation()).isEqualTo(38186860);}}服務端下載地址:
https://github.com/fengfanchen/Java/tree/master/SSLWebService
客戶端下載地址:
https://github.com/fengfanchen/Java/tree/master/SSLWebServiceClient
?
?
?
?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Java笔记-基于Spring Boot的SOAP双向SSL认证及WS-Security的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java笔记-使用logback按天生成
- 下一篇: C++Qt笔记-完美屏蔽IDEA中acc