如何为Apache Axis SOAP WebService添加IP访问限制过滤器?
我之前也碰到过类似的问题——普通Servlet过滤器确实没法直接抛出符合SOAP规范的Fault,因为Axis会自己接管请求的序列化和处理流程,过滤器里直接返回的内容不会被封装成SOAP格式。下面给你两种可行的解决方案,你可以根据自己的场景选择:
方案一:使用Axis自带的Request Handler(推荐)
Axis的架构基于Handler处理链,自定义一个Handler来做IP校验,能直接在Axis的请求流程中抛出标准的SOAPFault,是最贴合Axis生态的做法。
步骤1:自定义IP校验Handler
创建一个继承BasicHandler的类,在invoke方法里完成IP校验和异常抛出:
import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.handlers.BasicHandler; import org.apache.axis.utils.Messages; import org.apache.axis.constants.HTTPConstants; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; public class IPValidationHandler extends BasicHandler { // 可配置的可信IP列表,也可以从配置文件/数据库读取 private List<String> trustedIPs = Arrays.asList("192.168.1.100", "10.0.0.5"); @Override public void invoke(MessageContext msgContext) throws AxisFault { // 获取HTTP请求对象 HttpServletRequest request = (HttpServletRequest) msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST); String clientIP = request.getRemoteAddr(); // 【可选】如果服务在反向代理(如Nginx)后,需要读取X-Forwarded-For头获取真实IP // String clientIP = request.getHeader("X-Forwarded-For"); // if (clientIP != null && !clientIP.isEmpty()) { // clientIP = clientIP.split(",")[0].trim(); // } else { // clientIP = request.getRemoteAddr(); // } // IP校验逻辑 if (!trustedIPs.contains(clientIP)) { AxisFault fault = new AxisFault( Messages.getMessage("clientIPNotAllowed0"), new javax.xml.namespace.QName("http://your-service-namespace/errors", "IPValidationError"), null, "Access denied: Your IP " + clientIP + " is not authorized to access this service." ); throw fault; } } }
步骤2:配置Handler到Axis服务
在你的Axis服务配置文件services.xml中,把这个Handler添加到服务的处理链最前端,确保IP校验优先执行:
<service name="YourSOAPService" provider="java:RPC"> <!-- 原有服务配置:参数、操作定义等 --> <!-- 添加IP校验Handler --> <handler name="IPValidation" type="java:com.your-package.IPValidationHandler"/> <!-- 原有Handler(如RPC处理器) --> <handler name="RPC" type="java:org.apache.axis.handlers.RPCProvider"/> </service>
方案二:改进Servlet过滤器手动返回SOAPFault
如果不想修改Axis的服务配置,也可以改造Servlet过滤器,手动构建符合SOAP规范的错误响应,直接返回给客户端。
步骤1:自定义IP校验过滤器
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.List; public class IPValidationFilter implements Filter { private List<String> trustedIPs; @Override public void init(FilterConfig filterConfig) throws ServletException { // 从web.xml的初始化参数读取可信IP列表,更灵活 String ipList = filterConfig.getInitParameter("trustedIPs"); trustedIPs = ipList != null ? Arrays.asList(ipList.split(",")) : Arrays.asList("192.168.1.100"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String clientIP = httpRequest.getRemoteAddr(); // 【可选】处理反向代理场景的真实IP // String clientIP = httpRequest.getHeader("X-Forwarded-For"); // if (clientIP != null && !clientIP.isEmpty()) { // clientIP = clientIP.split(",")[0].trim(); // } if (trustedIPs.contains(clientIP)) { chain.doFilter(request, response); } else { // 手动构建SOAP Fault响应 httpResponse.setContentType("text/xml;charset=UTF-8"); httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); String soapFaultXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" + "<soapenv:Body>" + "<soapenv:Fault>" + "<faultcode>soapenv:Client</faultcode>" + "<faultstring>IP Validation Failed</faultstring>" + "<detail>" + "<errorMessage>Access denied: Your IP " + clientIP + " is not in the trusted list.</errorMessage>" + "</detail>" + "</soapenv:Fault>" + "</soapenv:Body>" + "</soapenv:Envelope>"; PrintWriter out = httpResponse.getWriter(); out.print(soapFaultXml); out.flush(); out.close(); } } @Override public void destroy() { // 清理资源(如果需要) } }
步骤2:配置过滤器到web.xml
将过滤器映射到Axis的Servlet路径(通常是/services/*):
<filter> <filter-name>IPValidationFilter</filter-name> <filter-class>com.your-package.IPValidationFilter</filter-class> <init-param> <param-name>trustedIPs</param-name> <param-value>192.168.1.100,10.0.0.5</param-value> </init-param> </filter> <filter-mapping> <filter-name>IPValidationFilter</filter-name> <url-pattern>/services/*</url-pattern> </filter-mapping>
两种方案对比
- 方案一:更贴合Axis的架构,异常处理完全遵循SOAP规范,能和Axis的其他Handler(如日志、权限)无缝集成,推荐用于正规项目。
- 方案二:无需修改Axis服务配置,实现快速,但需要手动维护SOAP XML格式,适合临时需求或小型项目。
内容的提问来源于stack exchange,提问作者Mrinal Sharma
相关产品推荐
相关产品推荐

