基於cxf開發webservice並設定header安全認證
阿新 • • 發佈:2020-11-05
服務端設定:
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, ""));