1.はじめに
WebServiceを使用する場合、WebServiceのセキュリティを考慮することがよくあります。一連のユーザー名とパスワードを使用して、違法なユーザーが電話をかけるのを防ぐことができます。
2、例
コードは引き続き使用されます:https://blog.csdn.net/cs373616511/article/details/112754986
1.サーバーに認証インターセプターを追加します
AuthInterceptor認証インターセプター
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.common.util.StringUtils;
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.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.soap.SOAPException;
import java.util.List;
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
Logger logger = LoggerFactory.getLogger(this.getClass());
private static final String USERNAME = "root";
private static final String PASSWORD = "root";
public AuthInterceptor() {
//定义在哪个阶段进行拦截
super(Phase.PRE_PROTOCOL);
}
@Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
List<Header> headers = null;
String username = null;
String password = null;
try {
headers = soapMessage.getHeaders();
} catch (Exception e) {
logger.error("getSOAPHeader error: {}", e.getMessage(), e);
}
if (headers == null) {
throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息"));
}
//获取用户名,密码
for (Header header : headers) {
SoapHeader soapHeader = (SoapHeader) header;
Element e = (Element) soapHeader.getObject();
NodeList usernameNode = e.getElementsByTagName("username");
NodeList pwdNode = e.getElementsByTagName("password");
username = usernameNode.item(0).getTextContent();
password = pwdNode.item(0).getTextContent();
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
throw new Fault(new IllegalArgumentException("用户信息为空"));
}
}
//校验用户名密码
if (!(USERNAME.equals(username) && PASSWORD.equals(password))) {
SOAPException soapExc = new SOAPException("认证失败");
logger.debug("用户认证信息错误");
throw new Fault(soapExc);
}
}
}
WebServiceConfig
構成クラスを変更してコードを追加します
endpoint.getInInterceptors()。add(new AuthInterceptor()); //検証インターセプターを追加します
import com.asyf.demo.service.ServiceDemo;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
@Configuration
public class WebServiceConfig {
@Autowired
private ServiceDemo serviceDemo;
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), serviceDemo);
endpoint.getInInterceptors().add(new AuthInterceptor());//添加校验拦截器
endpoint.publish("/ws/api");
return endpoint;
}
}
2.クライアント側にログインインターセプターを追加します
LoginInterceptor
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.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.namespace.QName;
import java.util.List;
public class LoginInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
private String username = "root";
private String password = "root";
public LoginInterceptor(String username, String password) {
//设置在发送请求前阶段进行拦截
super(Phase.PREPARE_SEND);
this.username = username;
this.password = password;
}
@Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
List<Header> headers = soapMessage.getHeaders();
Document doc = DOMUtils.createDocument();
Element auth = doc.createElementNS("http://cxf.wolfcode.cn/", "SecurityHeader");
Element UserName = doc.createElement("username");
Element UserPass = doc.createElement("password");
UserName.setTextContent(username);
UserPass.setTextContent(password);
auth.appendChild(UserName);
auth.appendChild(UserPass);
headers.add(0, new Header(new QName("SecurityHeader"), auth));
}
}
main関数はログインインターセプターを追加します
jaxWsProxyFactoryBean.getOutInterceptors()。add(new LoginInterceptor( "root"、 "root"));
public static void main(String[] args) {
String address = "http://127.0.0.1:8080/services/ws/api?wsdl";
// 代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
//添加用户名密码拦截器
jaxWsProxyFactoryBean.getOutInterceptors().add(new LoginInterceptor("root","root"));
// 设置接口类型
jaxWsProxyFactoryBean.setServiceClass(ServiceDemo.class);
// 创建一个代理接口实现
ServiceDemo cs = (ServiceDemo) jaxWsProxyFactoryBean.create();
// 数据准备
String data = String.valueOf(new Date());
// 调用代理接口的方法调用并返回结果
String rs = cs.emrService(data);
System.out.println("==============\n返回结果:" + rs);
}
3.テスト
(1)クライアントがログインインターセプターを追加しない
(2)クライアント側にログインインターセプターを追加する