Java 用于安全soap的springboot客户端

Java 用于安全soap的springboot客户端,java,spring-boot,authentication,soap,wsdl,Java,Spring Boot,Authentication,Soap,Wsdl,我试图从springboot客户端访问安全SOAP服务,但出现了此错误 开始交易。。。 equifax |启动事务。。。 equifax |服务初始化 equifax | 2018-09-20 07:50:38.512信息1-[nio-7070-exec-1]o.a.c.w.s.f.ReflectionServiceFactoryBean:从WSDL创建服务{}canadav3: equifax |服务端口初始化 equifax | 2018-09-20 07:50:39.558信息1-[nio

我试图从springboot客户端访问安全SOAP服务,但出现了此错误

开始交易。。。 equifax |启动事务。。。 equifax |服务初始化 equifax | 2018-09-20 07:50:38.512信息1-[nio-7070-exec-1]o.a.c.w.s.f.ReflectionServiceFactoryBean:从WSDL创建服务{}canadav3: equifax |服务端口初始化 equifax | 2018-09-20 07:50:39.558信息1-[nio-7070-exec-1]o.a.c.w.s.f.ReflectionServiceFactoryBean:从WSDL创建服务{}canadav3: equifax | 2018-09-20 07:50:39.614信息1-[nio-7070-exec-1]o.a.c.w.s.f.ReflectionServiceFactoryBean:从WSDL创建服务{}canadav3: 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();
}

}
}
然后我在调用soap服务时使用它 与这里的示例一样:SOAPLoggingHandler.java=>

示例–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();
       }

    }
}

这些日志是不够的,考虑添加更多的痕迹。这就是我所有的日志。也许,它的格式不太好: