我正在使用Spring Boot公开SOAP Web服务。此Web服务使用Web Service安全性(WSS)进行保护,该Web服务安全性是使用<< security_policy.xml:
配置的<xwss:SecurityConfiguration
xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:RequireUsernameToken
passwordDigestRequired="true" nonceRequired="true" />
</xwss:SecurityConfiguration>
直到这一点,应用程序运行正常。它能够成功进行身份验证。中添加以下值:现在,我需要基于WSS用户名添加特定的HTTP标头。也就是说,在HTTP标头
“ x-auth-type”
我以为添加EndpointInterceptor很容易,在其中可以基于用户设置HTTP标头,但直到现在我还是无法实现。
我的Web服务配置类如下:package com.godev.soapwebserviceswithspring;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.web.servlet.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 {
private static final String WS_SCHEMA_PATH = "godev_contract.xsd";
private static final String NAMESPACE_URI = "http://godev.com/soap/webservices/demo";
@Bean
public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(
ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean<>(servlet, "/ws/*");
}
@Bean(name = "xml_message")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema billsSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("XmlMessagePort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace(NAMESPACE_URI);
wsdl11Definition.setSchema(billsSchema);
return wsdl11Definition;
}
@Bean
public XsdSchema countriesSchema() {
return new SimpleXsdSchema(new ClassPathResource(WS_SCHEMA_PATH));
}
@Bean
PayloadLoggingInterceptor payloadLoggingInterceptor() {
return new PayloadLoggingInterceptor();
}
@Bean
PayloadValidatingInterceptor payloadValidatingInterceptor() {
final PayloadValidatingInterceptor payloadValidatingInterceptor = new PayloadValidatingInterceptor();
payloadValidatingInterceptor.setSchema(new ClassPathResource(WS_SCHEMA_PATH));
return payloadValidatingInterceptor;
}
@Bean
XwsSecurityInterceptor securityInterceptor() {
XwsSecurityInterceptor securityInterceptor = new XwsSecurityInterceptor();
securityInterceptor.setCallbackHandler(callbackHandler());
securityInterceptor.setPolicyConfiguration(new ClassPathResource("security_policy.xml"));
return securityInterceptor;
}
@Bean
SimplePasswordValidationCallbackHandler callbackHandler() {
SimplePasswordValidationCallbackHandler callbackHandler = new SimplePasswordValidationCallbackHandler();
callbackHandler.setUsersMap(Collections.singletonMap("admin", "pwd123"));
return callbackHandler;
}
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(payloadLoggingInterceptor());
interceptors.add(payloadValidatingInterceptor());
interceptors.add(securityInterceptor());
}
}
我的Web服务端点类看起来像这样:
package com.godev.soapwebserviceswithspring; import org.springframework.ws.server.endpoint.annotation.Endpoint; import org.springframework.ws.server.endpoint.annotation.PayloadRoot; import org.springframework.ws.server.endpoint.annotation.RequestPayload; import org.springframework.ws.server.endpoint.annotation.ResponsePayload; import com.godev.soap.webservices.demo.GetXmlMessageRequest; import com.godev.soap.webservices.demo.GetXmlMessageResponse; @Endpoint public class XmlMessageEndpoint { private static final String NAMESPACE_URI = "http://godev.com/soap/webservices/demo"; @PayloadRoot(namespace = NAMESPACE_URI, localPart = "getXmlMessageRequest") @ResponsePayload public GetXmlMessageResponse getXmlDocument(@RequestPayload GetXmlMessageRequest request) { GetXmlMessageResponse response = new GetXmlMessageResponse(); response.setXmlMessage("<xml>empty document</xml>"); return response; } }
任何建议将不胜感激!
在
Endpoint的SOAP头中注入Security元素:
@Endpoint
public class XmlMessageEndpoint {
private static final String NAMESPACE_URI = "http://godev.com/soap/webservices/demo";
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getXmlMessageRequest")
@ResponsePayload
public GetXmlMessageResponse getXmlDocument(@RequestPayload GetXmlMessageRequest request, @SoapHeader("{" + Security.SECURITY_NAMESPACE + "}Security") SoapHeaderElement securityHeader) {
GetXmlMessageResponse response = new GetXmlMessageResponse();
response.setXmlMessage("<xml>empty document</xml>");
return response;
}
为了将解析为可用的东西,您需要定义几个POJO。就我而言,我只需要usernamesecurityHeader
用于安全元素的POJO
:@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(namespace = Security.SECURITY_NAMESPACE, name = "Security")
@Getter
@Setter
public class Security {
public static final String SECURITY_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
@XmlElement(namespace = Security.SECURITY_NAMESPACE, name = "UsernameToken")
private UsernameToken usernameToken;
}
:UsernameToken元素的POJO
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(namespace = Security.SECURITY_NAMESPACE, name = "UsernameToken")
@Getter
@Setter
public class UsernameToken {
@XmlElement(namespace = Security.SECURITY_NAMESPACE, name = "Username")
private String username;
}
最后,您可以使用以下内容来解析:securityHeader
public class SoapParser {
public static Security parseSecurityElement(SoapHeaderElement soapHeaderElement) {
Security securityElement = null;
try {
JAXBContext context = JAXBContext.newInstance(Security.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
securityElement = (Security) unmarshaller.unmarshal(soapHeaderElement.getSource());
} catch (JAXBException e) {
e.printStackTrace();
}
return securityElement;
}
}
我希望这会有所帮助!