java - 用于安全肥皂的 springboot 客户端
问题描述
我正在尝试从 springboot 客户端访问安全的 SOAP 服务,但出现此错误
StartTransaction 开始... equifax | 开始交易... equifax | 服务初始化 equifax | 2018-09-20 07:50:38.512 信息 1 --- [nio-7070-exec-1] oacwsfReflectionServiceFactoryBean:创建服务 { http://eid.equifax.com/soap/schema/canada/v3/wsdl }canadav3来自 WSDL:https: //eid.equifax.ca/uru/soap/ut/canadav3? wsdl equifax | ServicePort 初始等值传真 | 2018-09-20 07:50:39.558 信息 1 --- [nio-7070-exec-1] oacwsfReflectionServiceFactoryBean:创建服务 { http://eid.equifax.com/soap/schema/canada/v3/wsdl }canadav3来自 WSDL:https ://eid.equifax.ca/uru/soap/ut/canadav3?wsdl 等传真 | 2018-09-20 07:50:39.614 信息 1 --- [nio-7070-exec-1] oacwsfReflectionServiceFactoryBean:创建服务 { http://eid.equifax.com/soap/schema/canada/v3/wsdl }canadav3来自 WSDL:https: //eid.equifax.ca/uru/soap/ut/canadav3? wsdl equifax | org.apache.cxf.binding.soap.SoapFault:处理标头 equifax 时发现错误 | 处理标头时发现错误
我的代码:
@ResponseBody
public ResponseEntity<Object> startTransaction(@RequestBody Identity identity) {
System.out.println("StartTransaction Started...");
InitialRequest initialRequest = new InitialRequest();
ProcessingOptions value = new ProcessingOptions();
value.setLanguage("French");
initialRequest.setIdentity(identity);
initialRequest.setProcessingOptions(value);
InitialResponse iR = new InitialResponse();
try {
System.out.println("Start transaction ...");
Canadav3 canada = new Canadav3();
System.out.println("Service initialise");
CanadaPortTypeV3 c = canada.getCanadaHttpPortV3();
System.out.println("ServicePort initiee");
URL wsdlURL = new URL("https://eid.equifax.ca/uru/soap/ut/canadav3?wsdl");
QName qname = new QName("http://eid.equifax.com/soap/schema/canada/v3/wsdl", "Canadav3");
Service service =Service.create(wsdlURL, qname);
c = (CanadaPortTypeV3)service.getPort(CanadaPortTypeV3.class);
BindingProvider bp = (BindingProvider)c;
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "/user");
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "mypassword");
iR = c.startTransaction(initialRequest);
System.out.println("Finish");
return ResponseEntity.status(HttpStatus.OK).body(iR);
}catch (CredentialsErrorFault c) {
System.err.println("Finish");
System.err.println("CredentialsErrorFault "+c.getLocalizedMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new Alert(c.getMessage()));
}
catch(ValidationErrorFault e) {
System.err.println("Finish");
System.err.println("ValidationErrorFault "+e.getLocalizedMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new Alert(e.getMessage()));
}
catch(Exception e) {
System.out.println(e.getCause());
System.err.println(e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new Alert("Error unknows"));
}
}
先感谢您
解决方案
我终于有了解决问题的方法
创建一个 SOAP 处理程序以将客户端身份验证信息注入到每个传出 SOAP 消息的 SOAP 标头块中。
import java.io.ByteArrayOutputStream;
import java.util.Set;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {
private static Logger logger = Logger.getLogger(SOAPLoggingHandler.class.getName());
public boolean handleMessage(SOAPMessageContext context) {
Boolean outGoingMsg = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
SOAPMessage soapMsg = context.getMessage();
if(soapMsg != null && soapMsg.getSOAPPart() != null) {
SOAPEnvelope soapEnv;
try {
soapEnv = soapMsg.getSOAPPart().getEnvelope();
SOAPHeader soapHeader = soapEnv.getHeader();
if (soapHeader == null) {
soapHeader = soapEnv.addHeader();
}
addAuthentication(soapHeader);
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (outGoingMsg)
System.out.println("########outgoing soap message######");
else
System.out.println("########incoming soap message############");
logSoapMessage(context);
return true;
}
public boolean handleFault(SOAPMessageContext context) {
System.out.println("########Fault soap message######");
logSoapMessage(context);
return true;
}
public void close(MessageContext context) {
}
public void logSoapMessage(SOAPMessageContext context) {
try {
SOAPMessage msg = context.getMessage();
ByteArrayOutputStream bas = new ByteArrayOutputStream();
msg.writeTo(bas);
System.out.println(bas);
}
catch (Exception e) {
System.out.println("Error while writing SOAP message to debug log " + e);
}
}
public Set<QName> getHeaders() {
return null;
}
private void addAuthentication(SOAPHeader header) {
try {
SOAPElement security =header.addChildElement("Security", "wsse", "http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken =
security.addChildElement("UsernameToken", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
username.addTextNode("/yourusername");
SOAPElement password =
usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode("yourpassword");
} catch (Exception e) {
e.printStackTrace();
}
}
}
然后我在调用肥皂服务时使用它就像这里一样(示例:SOAPLoggingHandler.java)=> https://www.juniper.net/documentation/en_US/junos-space16.1/topics/task/operational/junos- space-servicenow-tt-web-service-client-setting.html
示例——SOAPLoggingHandler.java
import java.io.ByteArrayOutputStream;
import java.util.Set;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {
private static Logger logger = Logger.getLogger(SOAPLoggingHandler.class.getName());
public boolean handleMessage(SOAPMessageContext context) {
Boolean outGoingMsg = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
SOAPMessage soapMsg = context.getMessage();
if(soapMsg != null && soapMsg.getSOAPPart() != null) {
SOAPEnvelope soapEnv;
try {
soapEnv = soapMsg.getSOAPPart().getEnvelope();
SOAPHeader soapHeader = soapEnv.getHeader();
if (soapHeader == null) {
soapHeader = soapEnv.addHeader();
}
addAuthentication(soapHeader);
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (outGoingMsg)
System.out.println("########outgoing soap message######");
else
System.out.println("########incoming soap message############");
logSoapMessage(context);
return true;
}
public boolean handleFault(SOAPMessageContext context) {
System.out.println("########Fault soap message######");
logSoapMessage(context);
return true;
}
public void close(MessageContext context) {
}
public void logSoapMessage(SOAPMessageContext context) {
try {
SOAPMessage msg = context.getMessage();
ByteArrayOutputStream bas = new ByteArrayOutputStream();
msg.writeTo(bas);
System.out.println(bas);
}
catch (Exception e) {
System.out.println("Error while writing SOAP message to debug log " + e);
}
}
public Set<QName> getHeaders() {
return null;
}
private void addAuthentication(SOAPHeader header) {
try {
SOAPElement security =
header.addChildElement("Security", "wsse", "http://docs.oasis- open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken =
security.addChildElement("UsernameToken", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username =
usernameToken.addChildElement("Username", "wsse");
username.addTextNode("***");
SOAPElement password =
usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode("***");
} catch (Exception e) {
e.printStackTrace();
}
}
}
推荐阅读
- java - 无法在java中使用硒单击复选框
- javascript - Vue父组件无法识别来自子组件的发射
- c++ - 在 windows 中使用 g++ 将 c++ 代码转换为 .asm x86
- python-3.x - Python BigQuery 异常:无法在 LegacySQL 中输出 HOUR 分区数据
- django - 'str' 对象没有属性 'get' django 错误
- javascript - 如何创建将域从本地主机更改为实际域名的链接
- sql - 如何将行转换为列 Sql Server
- r - 在ggplot2示例中从素食主义者绘制ordiellipse不起作用
- symfony - 无法自动装配方法“__construct()”的服务参数“$locales”是类型提示的“字符串”,你应该在 symfony 中显式配置它的值
- google-drive-api - Google Drive API - 上传文件失败c#