1. 程式人生 > 實用技巧 >基於cxf開發webservice並設定header安全認證

基於cxf開發webservice並設定header安全認證

服務端設定:

1、新增過濾器


import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import java.util.List;
import java.util.regex.Pattern;


/**
* 全域性攔截器
*/
@Component
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

private Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);

@Value(value = "${ENV_PWP_WSINTERFACE_SECURITY_ENABLED:true}")
private String securityEnabled;

public AuthInterceptor() {
//定義攔截器階段
super(Phase.PRE_INVOKE);
}

/**
* 攔截器操作
*
* @param message 被攔截到的訊息
* @throws Fault
*/
@Override
public void handleMessage(SoapMessage message) {

if (isEnableSecurity()) {
List<Header> headers = message.getHeaders();
if (CollectionUtils.isEmpty(headers)) {
throw new Fault(new SOAPException("安全認證未開啟"));
} else {
Element auth = null;
//獲取授權資訊元素
for (Header header : headers) {
QName qname = header.getName();
String tagName = qname.getLocalPart();
if ("security".equals(tagName)) {
auth = (Element) header.getObject();
break;
}
}
//如果授權資訊元素不存在,提示錯誤
if (auth == null) {
throw new Fault(new SOAPException("授權資訊元素不存在"));
}

String username = "";
String password = "";
try {
NodeList nodes = auth.getChildNodes();
if (nodes == null || nodes.getLength() == 0) {
throw new Fault(new Exception("使用者名稱或密碼為空"));
}
int size = nodes.getLength();

for (int i = 0; i < size; i++) {
Node node = nodes.item(i);
String tagName = node.getLocalName();
if ("username".equalsIgnoreCase(tagName)) {
username = node.getTextContent();
}
if ("password".equalsIgnoreCase(tagName)) {
password = node.getTextContent();
}

}
} catch (Exception e) {
throw new Fault(new Exception( e.getMessage()));
}
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
throw new Fault(new Exception("使用者名稱或密碼為空"));
}
if (!verification(username, password)) {
throw new Fault(new Exception("使用者名稱或密碼錯誤"));
}
}
}
}

/**
* handleMessage異常後執行
*
* @param message 被攔截到的訊息
*/
@Override
public void handleFault(SoapMessage message) {
super.handleFault(message);
}

private Boolean isEnableSecurity() {
return "true".equalsIgnoreCase(this.securityEnabled);
}


public boolean verification(String username, String password) {
if (!username.equals("aaaa")
|| !password.equals("bbb")) {
throw new Fault(new Exception("使用者名稱或密碼錯誤"));
}
return true;
}
}

2、釋出資訊webservice新增認證

客戶端配置

1、設定過濾器


import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

@Component
public class AuthSoapHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

private static Logger LOG = LoggerFactory.getLogger(AuthSoapHeaderInterceptor.class);

private String sys;

public AuthSoapHeaderInterceptor(String p, String sys) {
super(p);
this.sys = sys;
}

public AuthSoapHeaderInterceptor() {
super(Phase.WRITE);
}

@Override
public void handleMessage(SoapMessage message) throws Fault {

String username = "aaaa";
String password = "bbb";
System.out.println("-----攔截器開始----");
try {
boolean isEnableSecurity = true;
if (isEnableSecurity) {
// SoapHeader部分待新增的節點
QName qName = new QName("security");
Document doc = DOMUtils.createDocument();
// 驗證token
Element usernameEl = doc.createElement("username");
usernameEl.setTextContent(username);

Element passwordEl = doc.createElement("password");
passwordEl.setTextContent(password);
Element root = doc.createElement("security");

root.appendChild(usernameEl);
root.appendChild(passwordEl);
// 建立SoapHeader內容
SoapHeader header = new SoapHeader(qName, root);
// 新增SoapHeader內容
List<Header> headers = message.getHeaders();
headers.add(header);
}
} catch (Exception e) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(baos));
String exception = baos.toString();
LOG.error("soa安全認證頭部加入過程出現異常" + exception);

}
}
}

2、呼叫介面時設定過濾器部分程式碼
Service service= new Service();
ervicePort servicePort = service.getService();
Client client = ClientProxy.getClient(servicePort);
client.getOutInterceptors().add(new AuthSoapHeaderInterceptor(Phase.WRITE, ""));