在不使用过滤器和包装器的情况下删除 URL 中的 JSESSIONID

Posted

技术标签:

【中文标题】在不使用过滤器和包装器的情况下删除 URL 中的 JSESSIONID【英文标题】:Removing JSESSIONID in URL without using Filter and Wrapper 【发布时间】:2012-10-26 04:56:37 【问题描述】:

我创建了一个 Filter 监听 /* 的 url 模式,它将 HttpServletRequest 替换为 HttpServletRequestWrapper 实现。

我有一个Servlet,在这个Servlet 中,我使用h:graphicImage 来渲染从Apache 网络服务器获取的图像。

<h:graphicImage value="/locationInMyWebServer/myImage.jgp"></h:graphicImage>

当我点击用于访问此页面(包含图像)的 URL 时,图像没有显示为 JSESSIONID 被附加到我的图像名称中。正在形成的 URL 如下所示。

http:/myDomain/myServlet/../myImage.jpg;JSESSIONID=ABCDEFGHIJKLMM

因此,我使用了问题开头所述的Filter(有关此过滤器的更多详细信息是here)。

从这个Servlet 有一个用于登录的链接。当用户登录时,即使经过身份验证,相同的JSESSIONID 也会被保留。由于 Session ID 在登录之前和用户登录之后是相同的,这导致了 Session-fixation 攻击。

如何避免使用此过滤器并解决我在使用h:graphicImage 时将JSESSIONID 附加到图像的问题

PS:我不能使用<img src>,因为我的h:graphicImageh:commandLink里面

登录前和登录后,使用此Filter之前的会话ID不同

我已经在下面添加了相关代码。

以下代码来自我的web.xml,其中包含Filter 的条目

<filter> 
   <filter-name>URLSessionFilter</filter-name>
   <filter-class>myPackage.web.filter.URLSessionFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>URLSessionFilter</filter-name> 
   <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>

URLSessionFilter 中的代码如下,

public class URLSessionFilter implements Filter

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain   chain)
throws IOException, ServletException
  
        if (!(request instanceof HttpServletRequest))

  chain.doFilter(request, response);
  return;


HttpServletResponse httpResponse = (HttpServletResponse)response;

HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(httpResponse)

  public String encodeRedirectUrl(String url)
  
    return url;
  

  public String encodeRedirectURL(String url) 
    return url; 

  public String encodeUrl(String url) 
    return url; 

  public String encodeURL(String url) 
    return url;
  
;
chain.doFilter(request, wrappedResponse);
  

  public void init(FilterConfig filterConfig)
  
  

  public void destroy()
  
  

在我的 Servlet 中有一个链接,单击将显示哪个登录页面。代码如下,

<h:commandLink  action="#myBean.myMethod">
<h:graphicImage value="/myLocInWebserver/myImage.jpg">
</h:commandLink>

myBean.myMethod 中,我正在做一些数据库清理活动并重定向到登录页面。

【问题讨论】:

显然您的包装器实现已损坏?以 SSCCE 的风格展示它。至于无法使用&lt;img&gt;,这是没有意义的。 @BalusC 我已经添加了相关代码。希望清楚自己在做什么。正如你所说,我也怀疑某个地方的包装器实现被破坏了。但是,我无法弄清楚在哪里。 对不起,我误解了你的问题。我知道带有包装器的过滤器无法正常工作,并且它会导致会话固定攻击,正如您在标题中所说的那样。毕竟,您的具体问题实际上归结为:“我不想使用过滤器和包装器,即使它们工作正常,还有其他方法吗?”。因此,您的问题标题完全具有误导性。 @BalusC 很抱歉误导您。对不起。我现在已经编辑了我的标题。您能否在不使用过滤器和包装器的情况下提出任何其他方法,同时牢记所面临问题的背景。 ***.com/questions/11349064/…有解决方案 【参考方案1】:

另一种方法是避免 servlet 容器将某些内容解释为 URL。为此,您将避免使用任何特殊的 JSP 或 JSF 标记,而直接使用 html 标记。在您的情况下 - 可能如下所示:

<h:commandLink  action="#myBean.myMethod">
  <img src="#request.contextPath/myLocInWebserver/myImage.jpg"/>
</h:commandLink>

没有更多的&lt;h:graphicImage&gt; ...

您仍然希望在没有任何硬编码的情况下为上下文路径添加前缀 - 因此使用 #request.contextPath

我最近使用了这个解决方案,因为我正在将 JavaMelody 与我的应用程序集成,并为管理员提供了该工具的链接。然而,JavaMelody 以某种方式失败并附加了;jsessionid。因此,我目前正在生成如下 URL:

<a href="#request.contextPath/monitoring" 
   target="_blank" 
   class="ui-link ui-widget"
>
  Java Melody Performance Monitoring
</a>

而不是典型的 JSF 解决方案

<p:link value="Java Melody Performance Monitoring" 
        href="/monitoring" 
        target="_blank" 
/>

这根本行不通。

这个解决方案的好处是我现在可以逐个 URL 控制它,我不必担心全局设置 &lt;tracking-mode&gt;COOKIE&lt;/tracking-mode&gt;

【讨论】:

以上是关于在不使用过滤器和包装器的情况下删除 URL 中的 JSESSIONID的主要内容,如果未能解决你的问题,请参考以下文章

Jquery 循环 - 在不破坏缩略图分页器的情况下将图像包装在 div 标签中

为什么glDrawElments()在不使用任何着色器的情况下工作?

Angular:如何在不删除子元素的情况下删除包装器(父元素)?

如何在不删除子元素的情况下删除包装器(父元素)?

为啥 glDrawElments() 在不使用任何着色器的情况下工作?

如何在不使用 cytoscape.js 重绘图形的情况下删除特定边?