SpringBootはWebサービス(Apache CXF JAX-WS)(2)ID認証を統合します

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)クライアント側にログインインターセプターを追加する

おすすめ

転載: blog.csdn.net/cs373616511/article/details/113098199