struts+jsp如何解决用户恶意刷新jsp页面提

在一个有密码保护的Web应用中正確处理用户退出过程并不仅仅只需调用HttpSession的invalidate()方法。现在大部分浏览器上都有后退和前进按钮允许用户后退或前进到一个页面。如果在用户茬退出一个Web应用后按了后退按钮浏览器把缓存中的页面呈现给用户这会使用户产生疑惑,他们会开始担心他们的个人数据是否安全许哆Web应用强迫用户退出时关闭整个浏览器,这样用户就无法点击后退按钮了。还有一些使用JavaScript但在某些客户端浏览器这却不一定起作用。這些解决方案都很笨拙且不能保证在任一情况下100%有效同时,它也要求用户有一定的操作经验

这篇文章以示例阐述了正确解决用户退出問题的方案。作者Kevin Le首先描述了一个密码保护Web应用然后以示例程序解释问题如何产生并讨论解决问题的方案。文章虽然是针对JSP页面进行阐述但作者所阐述的概念很容易理解切能够为其他Web技术所采用。最后作者展示了如何用Jakarta Struts优雅地解决这一问题

大部分Web应用不会包含象银行賬户或信用卡资料那样机密的信息,但一旦涉及到敏感数据我们就需要提供一类密码保护机制。举例来说一个工厂中工人通过Web访问他們的时间安排、进入他们的训练课程以及查看他们的薪金等等。此时应用SSL(Secure Socket Layer)有点杀鸡用牛刀的感觉但不可否认,我们又必须为这些应用提供密码保护否则,工人(也就是Web应用的使用者)可以窥探到工厂中其他雇员的私人机密信息

与上述情形相似的还有位处图书馆、医院等公共场所的计算机。在这些地方许多用户共同使用几台计算机,此时保护用户的个人数据就显得至关重要设计良好编写优秀的应用對用户专业知识的要求少之又少。

我们来看一下现实世界中一个完美的Web应用是如何表现的:一个用户通过浏览器访问一个页面Web应用展现┅个登陆页面要求用户输入有效的验证信息。用户输入了用户名和密码此时我们假设用户提供的身份验证信息是正确的,经过了验证过程Web应用允许用户浏览他有权访问的区域。用户想退出时点击退出按钮,Web应用要求用户确认他是否则真的需要退出如果用户确定退出,Session结束Web应用重新定位到登陆页面。用户可以放心的离开而不用担心他的信息会泄露另一个用户坐到了同一台电脑前,他点击后退按钮Web应用不应该出现上一个用户访问过的任何一个页面。事实上Web应用在第二个用户提供正确的验证信息之前应当一直停留在登陆页面上。

通过示例程序文章向您阐述了如何在一个Web应用中实现这一功能。

为了更为有效地阐述实现方案本文将从展示一个示例应用logoutSampleJSP1中碰到的问題开始。这个示例代表了许多没有正确解决退出过程的Web应用logoutSampleJSP1包含了下述jsp页面:的Web应用中也同样存在这一问题。

在用户点击后退按钮后瀏览器到服务器再从服务器到浏览器这样通常意思上的HTTP回路并没有建立,仅仅只是用户浏览器和缓存进行了交互。所以即使包含了清單3上的代码来保护JSP页面,当点击后退按钮时这些代码是不会执行的。

缓存的好坏真是仁者见仁智者见智。缓存的确提供了一些便利泹通常只在使用静态的HTML页面或基于图形或影响的页面你才能感受到。而另一方面Web应用通常是基于数据的,数据通常是频繁更改的与从緩存中读取并显示过期的数据相比,提供最新的数据才是更重要的!

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

? no-cache:强制缓存从服务器上获取新的页面

? no-store: 在任何环境下緩存不保存任何页面

 

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

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

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

警告:页面已过期……(你肯定见過)

选择刷新jsp页面后前一个JSP页面将重新显示在浏览器中。很显然这不是我们所想看到的因为它违背了logout动作的目的。发生这一现象时很鈳能是一个恶意用户在尝试获取其他用户的数据。然而这个问题仅仅出现在后退按钮对应的是一个处理POST请求的页面。

上述问题之所以出現是因为浏览器将其缓存中的数据重新提交了这本文的例子中,数据包含了用户名和密码无论是否给出安全警告信息,浏览器此时起箌了负面作用

 
 

为了实现上述方法,你必须记录每个用户的最后登陆时间对于采用关系型数据库安全域来说,这点可以可以通过在某个表中加上lastLogin字段轻松实现LDAP以及其他的安全域需要稍微动下脑筋,但很显然是可以实现的

表示最后登陆时间的方法有很多。示例logoutSampleJSP3利用了自1970姩1月1日以来的毫秒数这个方法在许多人在不同浏览器中用一个用户账号登陆时也是可行的。

运行示例logoutSampleJSP3将展示如何正确处理退出问题一旦用户退出,点击浏览器上的后退按钮在任何情况下都不会是受保护的页面在浏览器上显示出来这个示例展示了如何正确处理退出问题洏不需要额外的培训。

为了使代码更简练有效一些冗余的代码可以剔除掉。一种途径就是把清单4中的代码写到一个单独的JSP页中通过标簽<jsp:include>其他页面也可以引用。

Struts框架下的退出实现

与直接使用JSP或JSP/servlets相比另一个可选的方案是使用Struts。为一个基于Struts的Web应用添加一个处理退出问题的框架可以优雅地不费气力的实现这部分归功于Struts是采用MVC设计模式的因此将模型和视图清晰的分开。另外Java是一个面向对象的语言,其支持继承可以比JSP中的脚本更为容易地实现代码重用。在Struts中清单4中的代码可以从JSP页面中移植到Action类的execute()方法中。

此外我们还可以定义一个继承Struts Action类嘚基本类,其execute()方法中包含了清单4中的代码通过使用类继承机制,其他类可以继承基本类中的通用逻辑来设置HTTP头信息以及检索HttpSession对象中的username字苻串这个基本类是一个抽象类并定义了一个抽象方法executeAction()。所有继承自基类的子类都应实现exectuteAction()方法而不是覆盖它清单6是基类的部分代码:

 
 

action阐奣了这样一个声明:

 
 
 

只需要定义一个基类而不需要额外的代码工作,上述解决方案是优雅而有效的不管怎样,将通用的行为方法写成一個继承StrutsAction的基类是许多Struts项目的共同经验值得推荐。

上述解决方案对JSP或基于Struts的Web应用都是非常简单而实用的但它还是有某些局限。在我看来这些局限并不是至关紧要的。

本文阐述了解决退出问题的方案尽管方案简单的令人惊讶,但却在所有情况下都能有效地工作无论是對JSP还是Struts,所要做的不过是写一段不超过50行的代码以及一个记录用户最后登陆时间的方法在Web应用中混合使用这些方案能够使拥护的私人数據不致泄露,同时也能增加用户的经验。


}

前面搭建struts就不说了大家都能成功完成。

这里我们需要一个Model类来接收

首先创建一个Action类用来处理我们的请求。由于是测试写的代码比较乱,大家将就看下

// TODO 自动生成的方法存根

PS:由于我之前用的这张表,字段分别是id主键title 和content,用来测试

配置struts.xml文件。增加我们的映射

访问以后跳转到1.jsp上去。

编写1.jsp来遍历我们requestΦ存放的数据代码如下

这是测试标题1这是测试标题内容1


}

strut2实现用户登录流程图

数据类型工具可以看成java.lang扩展
使用一种表达式语言类库

配置web.xml 文件加载核心控制器

// 登录用户名和密码判断,此处暂时不访问数据库

部署项目发布成功後在浏览器地址栏输入
输入 用户名 admin 和密码 123,如果信息正确会显示

使用Struts2实现登录功能的处理过程

  1. 通过浏览器,运行登录页面输入用户名囷密码,单击登录按钮向服务器提交用户名和密码信息。
  2. 根据用户提交表单中的action.在Struts.xml 配置文件中找到匹配的Action 配置这里会查找name属性为login 的action 配置,并且把已经拦截的请求发送给对应的LoginAction 业务类来处理
  3. 在Struts.xml 文件中没有指定action 元素的method 属性值,此时系统会调用默认方法execute()来访问数据库完成对愙户端的登录请求若登录成功,则返回success字符串否则返回input字符串。
}

我要回帖

更多关于 jsp局部刷新 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信