SpringBoot整合WebServices(Apache CXF JAX-WS)(二)身份认证

一、简介

在使用WebService时我们经常会考虑WebService的安全问题,可以通过一组用户名与密码来防止非法用户的调用 。

二、示例

代码沿用:https://blog.youkuaiyun.com/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)客户端添加登录拦截器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值