如何使用 Apache cxf / jaxrs 拒绝非 https 请求

How to reject non-https request with Apache cxf / jaxrs

我需要做的事情: 我需要弄清楚如何拒绝任何未通过 TLS(即 https)的传入 http 请求。理想情况下,如果请求未通过 https,我将能够 return HTTP 状态 404(未找到)。

我的实现是这样的: 我正在使用 Apache cxf/jaxrs 实现 REST 服务。 我正在使用 Spring 的 IoC 来创建服务。

Spring 应用程序上下文文件中的服务定义如下所示:

<jaxrs:server id="testSvc" address="/">
    <jaxrs:serviceBeans>
        <ref bean="svcBean"/>
    </jaxrs:serviceBeans>    
</jaxrs:server>

服务在 Tomcat 内 运行。

我正在考虑使用简单的 servlet 过滤器或 jax-rs 过滤器(例如扩展 javax.ws.rs.container.ContainerRequestFilter 的东西)。

有更好的方法吗?

您只能在 SSL/TLS 上发布 tomcat,但我想您不能这样做,因此您可以检测自己是否处于 SSL 会话中。要从请求中访问 SSL 会话 ID,请使用:

//Tomcat 6
String sslID = (String)request.getAttribute("javax.servlet.request.ssl_session"); 

//Tomcat 7
String sslID = (String)request.getAttribute("javax.servlet.request.ssl_session_id"); 

tomcat SSL documentation

最后在 CXF 中设置一个 ContainerRequestFilter 以访问请求参数并在需要时中止响应

public class SSLFilter implements ContainerRequestFilter {

   public void filter(ContainerRequestContext context) {

       //get current httpservletRequest from CXFMessage
       Message message = JAXRSUtils.getCurrentMessage();
       HttpServletRequest request = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);

       //Get SSL session ID
       String sslID = (String)request.getAttribute("javax.servlet.request.ssl_session"); 

      // finally use context.abortWith(Response) if you need to block the request 
       if (sslId == null){
           Response response =   Response.status(Response.Status.UNAUTHORIZED).build();
           context.abortWith(response);
       }
  }

provider 添加到您的服务器

<bean id="sslFilter" class="SSLFilter">
<jaxrs:server id="testSvc" address="/">
   <jaxrs:providers>
      <ref bean="sslFilter" />
   </jaxrs:providers>
</jaxrs:server>