科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件正确的解决用户退出问题―JSP和Struts (2)

正确的解决用户退出问题―JSP和Struts (2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

四. 阻止未经认证访问受保护的JSP页面 从提交的form中获取用户提交的认证信息并经过验证后,登陆动作仅仅在HttpSession对象中写入一个用户名。退出动作则刚好相反,它从HttpSession中删除用户名并调用HttpSession对象的invalidate()方法。为了使登陆和退出动作真正发挥作用,

作者:sunshyman 来源:赛迪网 2007年8月29日

关键字: Struts JSP

  • 评论
  • 分享微博
  • 分享邮件
 

四. 阻止未经认证访问受保护的JSP页面

从提交的form中获取用户提交的认证信息并经过验证后,登陆动作仅仅在HttpSession对象中写入一个用户名。退出动作则刚好相反,它从HttpSession中删除用户名并调用HttpSession对象的invalidate()方法。为了使登陆和退出动作真正发挥作用,所有受保护的JSP页面必须首先验证HttpSession中包含的用户名,以便确认用户当前是否已经登陆。如果HttpSession中包含了用户名,就说明用户已经登陆,Web应用会将剩余的JSP页中的动态内容发送给浏览器。否则,JSP页将跳转到登陆页面,login.jsp。页面home.jsp, secure1.jsp, secure2.jsp和 logout.jsp均包含清单3中的代码段:

Listing 3

//... 
String userName = (String) session.getAttribute( "User" );
if (null == userName) {
    request.setAttribute( "Error" , "Session has ended. Please login." );
    RequestDispatcher rd = request.getRequestDispatcher( "login.jsp" );
    rd.forward(request, response);
}
//... 
//Allow the rest of the dynamic content in this JSP to be served to the browser 
//...

在这个代码段中,程序从HttpSession中检索username字符串。如果username字符串为空,Web应用则自动中止执行当前页面并跳转到登陆页,同时给出错误信息“Session has ended. Please log in.”;如果不为空,Web应用继续执行,把剩余的页面提供给用户,从而使JSP页面的动态内容成为服务对象。

五.运行logoutSampleJSP1

运行logoutSampleJSP1将会出现如下几种情形:

• 如果用户没有登陆,Web应用将会正确中止受保护页面home.jsp, secure1.jsp, secure2.jsp和logout.jsp中动态内容的执行。也就是说,假如用户并没有登陆,但是在浏览器地址栏中直接敲入受保护JSP页的地址试图访问,Web应用将自动跳转到登陆页面,同时显示错误信息“Session has ended.Please log in.”

• 同样的,当一个用户已经退出,Web应用将会正确中止受保护页面home.jsp, secure1.jsp, secure2.jsp和logout.jsp中动态内容的执行。也就是说,用户退出以后,如果在浏览器地址栏中直接敲入受保护JSP页的地址试图访问,Web应用将自动跳转到登陆页面,同时显示错误信息“Session has ended.Please log in.”

• 用户退出以后,如果点击浏览器上的后退按钮返回到先前的页面,Web应用将不能正确保护受保护的JSP页面——在Session销毁后(用户退出)受保护的JSP页会重新显示在浏览器中。然而,点击该页面上的任何链接,Web应用都会跳转到登陆页面,同时显示错误信息“Session has ended.Please log in.”

六. 阻止浏览器缓存

上述问题的根源就在于现代大部分浏览器都有一个后退按钮。当点击后退按钮时,默认情况下浏览器不会从Web服务器上重新获取页面,而是简单的从浏览器缓存中重新载入页面。这个问题并不仅限于基于Java(JSP/servlets/Struts) 的Web应用当中,在基于PHP (Hypertext Preprocessor)、ASP、(Active Server Pages)、和.NET的Web应用中也同样存在。

在用户点击后退按钮之后,浏览器到Web服务器(一般来说)或者应用服务器(在java的情况下)再从服务器到浏览器这样通常意义上的HTTP回路并没有建立。仅仅只是用户,浏览器和缓存之间进行了交互。所以即使受保护的JSP页面,例如home.jsp, secure1.jsp, secure2.jsp和logout.jsp包含了清单3上的代码,当点击后退按钮时,这些代码也永远不会执行的。

缓存的好坏,真是仁者见仁智者见智。缓存事实上的确提供了一些便利,但这些便利通常只存在于静态的HTML页面或基于图形或影像的页面。而另一方面,Web应用通常是面向数据的。由于Web应用中的数据频繁变更,所以与为了节省时间从缓存中读取并显示过期的数据相比,提供最新的数据显得尤为重要!

幸运的是,HTTP头信息“Expires”和“Cache-Control”为应用程序服务器提供了一个控制浏览器和代理服务器上缓存的机制。HTTP头信息Expires告诉代理服务器它的缓存页面何时将过期。HTTP1.1规范中新定义的头信息Cache-Control在Web应用当中可以通知浏览器不缓存任何页面。当点击后退按钮时,浏览器发送Http请求道应用服务器以便获取该页面的最新拷贝。如下是使用Cache-Control的基本方法:

• no-cache:强制缓存从服务器上获取该页面的最新拷贝

• no-store: 在任何情况下缓存不保存该页面

HTTP1.0规范中的Pragma:no-cache等同于HTTP1.1规范中的Cache-Control:no-cache,同样可以包含在头信息中。

通过使用HTTP头信息的cache控制,第二个示例应用logoutSampleJSP2解决了logoutSampleJSP1的问题。logoutSampleJSP2与logoutSampleJSP1不同表现在如下代码段中,这一代码段加入进所有受保护的页面中:

//... 
response.setHeader( "Cache-Control" , "no-cache" ); 
//Forces caches to obtain a new copy of the page from the origin server 
response.setHeader( "Cache-Control" , "no-store" ); 
//Directs caches not to store the page under any circumstance 
response.setDateHeader( "Expires" , 0); 
//Causes the proxy cache to see the page as "stale" 
response.setHeader( "Pragma" , "no-cache" );
//HTTP 1.0 backward compatibility 
String userName = (String) session.getAttribute( "User" );
if (null == userName) {
    request.setAttribute( "Error" , "Session has ended. Please login." );
    RequestDispatcher rd = request.getRequestDispatcher( "login.jsp" );
    rd.forward(request, response);
}
//...

通过设置头信息和检查HttpSession对象中的用户名来确保浏览器不会缓存JSP页面。同时,如果用户未登陆,JSP页面的动态内容不会发送到浏览器,取而代之的将是登陆页面login.jsp。

七. 运行logoutSampleJSP2

运行Web示例应用logoutSampleJSP2后将会看到如下结果:

• 当用户退出后试图点击后退按钮,浏览器不会重新显示受保护的页面,它只会显示登陆页login.jsp同时给出提示信息Session has ended. Please log in.

• 然而,当按了后退按钮返回的页是处理用户提交数据的页面时,IE和Avant浏览器将弹出如下信息提示:

警告:页面已过期

The page you requested was created using information you submitted in a form. This page is no longer available. As a security divcaution, Internet Explorer does not automatically resubmit your information for you.

Mozilla和FireFox浏览器将会显示一个对话框,提示信息如下:

The page you are trying to view contains POSTDATA that has expired from cache. If you resend the data, any action from the form carried out (such as a search or online purchase) will be repeated. To resend the data, click OK. Otherwise, click Cancel.

在IE和Avant浏览器中选择刷新或者在Mozilla和FireFox浏览器中选择重新发送数据后,前一个JSP页面将重新显示在浏览器中。显然的,这病不是我们所想看到的因为它违背了logout动作的目的。发生这一现象时,很可能是一个恶意用户在尝试获取其他用户的数据。然而,这个问题仅仅出现在点击后退按钮后,浏览器返回到一个处理POST请求的页面。

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章