我设法创建了一个肥皂服务器和客户端,需要用户名和密码才能调用函数。以下代码显示了我是如何完成此操作的
客户:
package hello;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
import org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor;
import org.springframework.ws.soap.security.xwss.callback.SpringUsernamePasswordCallbackHandler;
@Configuration
public class SoftlayerConfiguration {
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("be.elision.soap.cloud");
return marshaller;
}
@Bean
public SoftlayerClient softlayerClient(Jaxb2Marshaller marshaller) {
SoftlayerClient client = new SoftlayerClient();
client.setDefaultUri("http://192.168.137.107:8080/ws");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
client.setInterceptors(new ClientInterceptor[]{securityInterceptor()});
return client;
}
@Bean
XwsSecurityInterceptor securityInterceptor() {
XwsSecurityInterceptor securityInterceptor = new XwsSecurityInterceptor();
securityInterceptor.setSecureRequest(true);
securityInterceptor.setValidateRequest(true);
securityInterceptor.setCallbackHandler(callbackHandler());
securityInterceptor.setPolicyConfiguration(new ClassPathResource("securityPolicy.xml"));
return securityInterceptor;
}
@Bean
SpringUsernamePasswordCallbackHandler callbackHandler() {
SecurityContextHolder.setContext(new SecurityContextImpl());
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("user", "password"));
return new SpringUsernamePasswordCallbackHandler();
}
}
服务器
package be.elision.main;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor;
import org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor;
import org.springframework.ws.soap.security.xwss.callback.SimplePasswordValidationCallbackHandler;
import org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;
@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
@Bean
public ServletRegistrationBean messageDispatcherServlet(
ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
@Bean(name = "devices")
public DefaultWsdl11Definition defaultWsdl11Definition(
XsdSchema devicesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("DevicesPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://elision.be/soap/cloud");
wsdl11Definition.setSchema(devicesSchema);
return wsdl11Definition;
}
// toevoegen van xsd aan bean
@Bean
public XsdSchema devicesSchema() {
return new SimpleXsdSchema(new ClassPathResource("devices.xsd"));
}
@Bean
XwsSecurityInterceptor securityInterceptor() {
XwsSecurityInterceptor securityInterceptor = new XwsSecurityInterceptor();
securityInterceptor.setCallbackHandler(callbackHandler());
securityInterceptor.setPolicyConfiguration(new ClassPathResource(
"securityPolicy.xml"));
return securityInterceptor;
}
@Bean
SimplePasswordValidationCallbackHandler callbackHandler() {
SimplePasswordValidationCallbackHandler callbackHandler = new SimplePasswordValidationCallbackHandler();
callbackHandler.setUsersMap(Collections
.singletonMap("user", "password"));
return callbackHandler;
}
@Bean
PayloadLoggingInterceptor payloadLoggingInterceptor() {
return new PayloadLoggingInterceptor();
}
@Bean
PayloadValidatingInterceptor payloadValidatingInterceptor() {
final PayloadValidatingInterceptor payloadValidatingInterceptor = new PayloadValidatingInterceptor();
payloadValidatingInterceptor.setSchema(new ClassPathResource(
"devices.xsd"));
return payloadValidatingInterceptor;
}
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(payloadLoggingInterceptor());
interceptors.add(payloadValidatingInterceptor());
interceptors.add(securityInterceptor());
}
}
安全政策:
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:UsernameToken digestPassword="false" useNonce="false" />
</xwss:SecurityConfiguration>
但现在我想用证书替换此用户名和密码身份验证。我不想在xml中这样做,而是在我现有的代码中实现它,如上所示。
答案 0 :(得分:1)
我们几个月前最终想到了这一点,我记得我们的配置看起来像这样。
将此添加到您的web.xml
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
这需要出现在你的mvc-dispatcher-servlet.xml
中 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/web-services
http://www.springframework.org/schema/web-services/web-services-2.0.xsd">
<context:component-scan base-package="com.yourpackage" />
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory" />
<property name="defaultUri"
value="${backend.ip}devices" />
<property name="interceptors">
<list>
<ref local="xwsSecurityInterceptor" />
</list>
</property>
</bean>
<bean id="xwsSecurityInterceptor"
class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
<property name="policyConfiguration" value="/WEB-INF/securityPolicy.xml" />
<property name="callbackHandlers">
<list>
<ref bean="keyStoreHandler" />
</list>
</property>
</bean>
<bean id="keyStore"
class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
<property name="password" value="yourpassword" />
<property name="location" value="/WEB-INF/yourkeystore.jks" />
</bean>
<bean id="keyStoreHandler"
class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
<property name="keyStore" ref="keyStore" />
<property name="privateKeyPassword" value="yourpassword" />
<property name="defaultAlias" value="client" />
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!-- LOAD PROPERTIES -->
<context:property-placeholder
location="WEB-INF/config.properties"
ignore-unresolvable="true" />
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
</beans>
jks文件是一个包含证书的java密钥库文件。
SecurityPolicy.xml
<xwss:SecurityConfiguration dumpMessages="true" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:Sign includeTimestamp="true">
<xwss:X509Token certificateAlias="yourcertificatealias" />
</xwss:Sign>
</xwss:SecurityConfiguration>
这一切都是使用oracle的xws-security库完成的,你需要以下依赖项。
<dependency>
<groupId>com.sun.xml.wss</groupId>
<artifactId>xws-security</artifactId>
<version>3.0</version>
<exclusions>
<exclusion>
<groupId>javax.xml.crypto</groupId>
<artifactId>xmldsig</artifactId>
</exclusion>
</exclusions>
</dependency>
在我们在这本很棒的书中找到关于证书身份验证的一些很好的解释后,我们完成了这项工作!
&#39; Spring Web Services 2 Cookbook,作者:Hamidreza Sattari&#39;
如果您对此实施有任何疑问,请随便提出! :d