【问题标题】:How to reject non-https request with Apache cxf / jaxrs如何使用 Apache cxf / jaxrs 拒绝非 https 请求
【发布时间】:2016-12-22 01:20:29
【问题描述】:

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

我的实现是什么样的: 我正在使用 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 的东西)。

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: tomcat https jax-rs cxf servlet-filters


    【解决方案1】:

    您只能在 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>
    

    【讨论】:

    • 很好的回应,但在我的问题中,我将 ContainerRequestFilter 确定为 可能 解决方案,但要问一个问题:“有没有更好的方法来做到这一点?”我正在寻找 servlet 过滤器或 ContainerRquestFilter 以外的解决方案。
    • 最简单的解决方案是在 tomcat 或 SSL 代理上禁用 http 协议。但我假设您需要其他服务。接受 http / https 适当的解决方案是过滤器。 J2EE 标准过滤器不允许对每个服务器进行定制。您也可以考虑使用 CXF 拦截器,但中止请求并不是那么简单。由于 CXF3.0 ContextRequestFilter 可用于此类操作(在调用服务方法之前预处理消息)
    • 对我来说不幸的是,我被困在 CXF 2.2.12 上。该版本中不存在 ContextRequestFilter。所以,我最终使用了 CXF 拦截器。它似乎工作正常。
    • 如果你不喜欢拦截器,对于 CXF 2. 2 你可以使用 RequestHandler 而不是 ContextRequestFilter。它们相似,请在此处查看差异stackoverflow.com/a/37730218/6371459
    猜你喜欢
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 2013-06-28
    • 2011-02-28
    • 1970-01-01
    • 2013-08-22
    相关资源
    最近更新 更多