首页 > 解决方案 > 用于安全肥皂的 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"));
    }
}

先感谢您

标签: javaspring-bootauthenticationsoapwsdl

解决方案


我终于有了解决问题的方法

创建一个 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();
       }

    }
}

推荐阅读