dwr session error-程序员宅基地

http://blog.sina.com.cn/s/blog_5f044a4d010185pn.html
在使用dwr的时候遇到了session error 错误解决方法,就是在web.xml 中配置如下:
<!-- DWR servlet,生产环境应该Debug为false -->
<servlet>
   <servlet-name>dwr-invoker</servlet-name>
   <servlet-class>
    org.directwebremoting.servlet.DwrServlet
   </servlet-class>
   <init-param>
    <param-name>debug</param-name>
    <param-value>true</param-value>
   </init-param>
   <init-param>
    <param-name>logLevel</param-name>
    <param-value>warn</param-value>
   </init-param>
   <init-param>
    <param-name>crossDomainSessionSecurity</param-name>
    <param-value>false</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>
当中的那个 
<init-param>
    <param-name>crossDomainSessionSecurity</param-name>
    <param-value>false</param-value>
   </init-param>


是为处理这个问题而加入的,经验证的确好用。

这是同源策略的问题,为了WEB环境的安全,在WEB脚本语言中不允许读取不同源的数据,同源包括相同协议,相同域名和相同端口三个条件,可以看这里:
http://www.ynutx.net/raindesign/blog/archive/209.html
而Ajax的异步处理方式跳过了这个限制,为了安全限制,它设置为sameDomainAccess,
这里有些突破这种限制的方式:http://tech.it168.com/j/2007-07-19/200707191542718_1.shtml
以上是自己的理解,不当之处请指正....!

 

 

另外装载了一篇

使用的Dwr版本2.0
在一台服务器上的不同端口上部署了同样的程序(tomcat5.5.28 80端口,tomcat 5.5.28 8080端口)
使用浏览器先后登陆80,8080端口的程序,都不注销,保持会话状态。
然后浏览器切换到8080的一个使用了DWR ajax功能的页面上,浏览器弹出Session Error的提示。
但是,如果切换到80端口的程序上,同样进入到一个使用了dwr ajax技术的页面上,没有Session Error的提示。
问题诊断:
初步怀疑浏览器的问题。
检查浏览器的cookie中的jsessionid的值。因为我们知道,Http协议本身是无状态的,服务器标识同一次会话的过程就是借助于cookie中的某个值或者通过url重写的方式来实现。这也是jsp程序的session原理。
检查发现:cookie中存在2个sessionid项,sessionid的值不同。
因为站点地址相同,url也相同(除了端口不同外),因此,浏览器“误”认为是同一个程序,把缓存的cookie项都发送回了服务器。
然后再观测ajax请求的值,即http post或get的参数值如下:


 



callCount=1

page=/web/initRolePermission.action

httpSessionId=3F5F7D7C14D40667FF126DC6F9038EE5

scriptSessionId=5B2B53E512648E78C92393E052589CA3859

c0-scriptName=adminRolePerAction

c0-methodName=findPermission

c0-id=0

c0-param0=string:181

batchId=0

在这里,务必注意

httpSessionId=3F5F7D7C14D40667FF126DC6F9038EE5,

实际上,一般情况下,httpSessionId和cookie中的jsession值是相同的。

至于dwr组件中,为什么要加上httpSessionId,这是因为dwr开发团队考虑到了跨站攻击问题。因此,通过验证dwr ajax请求中的httpSessionId值,

来防止跨站攻击。

在重现,诊断问题过程中,发现Session Error的信息是来自dwr ajax请求的响应中,抛出的异常是java.lang.SecurityException,

因此可以怀疑这个错误信息是源于dwr源代码中的。

用Eclipse打开下载到的dwr源代码。搜索Session Error的信息,然后在org.directwebremoting.dwrp.Batch 类中找到了,其部分代码如下:

private void checkNotCsrfAttack(HttpServletRequest request, String sessionCookieName)

{

// A check to see that this isn't a csrf attack

// http://en.wikipedia.org/wiki/Cross-site_request_forgery

// http://www.tux.org/~peterw/csrf.txt

if (request.isRequestedSessionIdValid() && request.isRequestedSessionIdFromCookie())

{

String headerSessionId = request.getRequestedSessionId();

if (headerSessionId.length() > 0)

{

String bodySessionId = getHttpSessionId();

// Normal case; if same session cookie is supplied by DWR and

// in HTTP header then all is ok

if (headerSessionId.equals(bodySessionId))

{

return;

}

// Weblogic adds creation time to the end of the incoming

// session cookie string (even for request.getRequestedSessionId()).

// Use the raw cookie instead

Cookie[] cookies = request.getCookies();

for (int i = 0; i < cookies.length; i++)

{

Cookie cookie = cookies[i];

if (cookie.getName().equals(sessionCookieName) &&

cookie.getValue().equals(bodySessionId))

{

return;

}

}

// Otherwise error

log.error("A request has been denied as a potential CSRF attack.");

throw new SecurityException("Session Error");

}

}

}

仔细分析这段代码,即使在上述问题情境环境中,也不会出现Session Error的错误。

然后反编译正在使用的dwr类文件,找到batch类,代码却不同,代码如下:

private void checkNotCsrfAttack(HttpServletRequest request)

{

if(request.isRequestedSessionIdValid() && request.isRequestedSessionIdFromCookie())

{

String headerSessionId = request.getRequestedSessionId();

if(headerSessionId.length() > 0)

{

String bodySessionId = getHttpSessionId();

if(!bodySessionId.startsWith(headerSessionId))

throw new SecurityException("Session Error");

}

}

}

该代码没有考虑到cookie中出现多个jsession的情况。

到此,问题就发现并解决。

 由于dwr低版本的bug引起的,升级dwr版本即解决此问题。

可能,读者还有一个疑问:为什么该问题只出现在8080端口上。

检查发现:80端口的cookie项(就是80端口产生的jsessionid出现在cookie项的最前面),

这样在80端口上的程序访问中,dwr ajax请求中的httpSessionId和cookie项最前面的jsessionid值相同,在80端口上,就自然不会出现session error错误。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qingfengxia2013/article/details/82188923

智能推荐

【笔记】strftime的使用方法-程序员宅基地

文章浏览阅读5.1k次。strftimestrftime是C语言标准库中用来格式化输出时间的的函数。下面是strftime的用法各参数意义代码使用示例#include<stdio.h>#include<time.h>#define print(s1, s2,s3) \ printf("%-20s%-30s%s\n",s1, s2,s3);int main(){ time_t rawtime; struct tm* timeinfo; char timE[80]; /

2018.09.12 poj3621Sightseeing Cows(01分数规划+spfa判环)-程序员宅基地

文章浏览阅读147次。传送门 01分数规划板题啊。 发现就是一个最优比率环。 这个直接二分+spfa判负环就行了。 代码:#include&lt;iostream&gt;#include&lt;cstdio&gt;#include&lt;cstring&gt;#include&lt;algorithm&gt;#include&lt;cmath&gt;#define N 1005#define...

hive sql的常用日期处理函数总结_hive sql 日期函数-程序员宅基地

文章浏览阅读3.1k次,点赞2次,收藏14次。1)date_format函数(根据格式整理日期)  作用:把一个字符串日期格式化为指定的格式。select date_format('2017-01-01','yyyy-MM-dd HH:mm:ss'); --日期字符串必须满足yyyy-MM-dd格式   结果:2017-01-01 00:00:002)date_add、date_sub函数(加减日期)  作用:把一个字符串日期格式加一天、减一天。select date_add('2019-01-01',1); ..._hive sql 日期函数

Android Studio使用百度语音合成是TTS时报错: ****.so文件找不到的有关问题_旧版的百度语言合成报错-程序员宅基地

文章浏览阅读2.1k次。使用百度语音合成过程时,一直error : notfint libgnustl_shared.so在项目工程gradle文件中添加如下代码段:sourceSets { main { jniLibs.srcDirs = ['libs'] } }..._旧版的百度语言合成报错

BZOJ1202: [HNOI2005]狡猾的商人_狡猾的商人[hnoi2005]-程序员宅基地

文章浏览阅读425次。Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的。账本上记录了n个月以来的收入情况,其中第i个月的收入额为Ai(i=1,2,3…n-1,n), 。当 Ai大于0时表示这个月盈利Ai 元,当 Ai小于0时表示这个月亏损Ai元。所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和。 刁姹的任务是秘密进行的,为了调查商人的账本,她只好跑到商人那_狡猾的商人[hnoi2005]

HTML5 Web SQL 数据库_方式准则的定义-程序员宅基地

文章浏览阅读1k次。1、HTML5 Web SQL 数据库 Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs。如果你是一个 Web 后端程序员,应该很容易理解 SQL 的操作。Web SQL 数据库可以在最新版的 Safari, Chrome 和 Opera 浏览器中工作。2、核心方法 以下是规范中定义的三个_方式准则的定义

随便推点

如何设置一个计算机用户访问磁盘,登录后限制用户访问硬盘分区-程序员宅基地

文章浏览阅读1.3k次。限制用户登录后访问硬盘分区。我们的部门有一台公用计算机,该计算机由我维护。其他同事也可以偶尔使用它。我在操作系统中为自己创建了一个超级管理员用户,还创建了一个受限用户。登录到计算机后,如何允许受限用户查看但不能访问用于存储重要文件的D分区?您可以通过以下操作实现该目标:在系统桌面上使用鼠标依次选择“开始”。在弹出窗口的“打开”(Open)字段中键入gpedit.msc,然后单击“确定”(OK)按钮..._win7 分区只能某个用户打开

更改vscode Java项目的.class文件输出路径_vscode怎么class文件-程序员宅基地

文章浏览阅读6.7k次,点赞17次,收藏21次。1.在vscode里面按下快捷键ctrl+shift+p2.输入Classpath3.点击Output下的Browse选择.class文件的输出路径4.如图,选择完以后,.class文件的输出层级目录会自动建立_vscode怎么class文件

Python缩进规则-程序员宅基地

文章浏览阅读1.2w次,点赞4次,收藏24次。python的缩进规则:对于类定义、函数定义、流程控制语句、异常处理语句等,行尾的冒号和下一行的缩进,表示下一个代码块的开始,而缩进的结束则表示此代码块的结束。通常情况下都是采用4个空格长度作为一个缩进量(一个Tab键就表示4个空格)。一,Python缩进长度及缩进字符。 看到网上一些Python缩进的错误示范,“tab符和空格不能混用”,“缩进一定是4个空格”下列演示。​def change(a): print(id(a)) # 指向的是同一个对象(tab缩进) a=10_python缩进规则

微信小程序api视频课程-定时器-setTimeout的使用_微信小程序 settimeout 向上层传值-程序员宅基地

文章浏览阅读1.1k次。JS代码 /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { setTimeout( function(){ wx.showToast({ title: '黄菊华老师', }) },2000 ) },说明该代码只执行一次..._微信小程序 settimeout 向上层传值

uploadify2.1.4如何能使按钮显示中文-程序员宅基地

文章浏览阅读48次。uploadify2.1.4如何能使按钮显示中文博客分类:uploadify网上关于这段话的搜索恐怕是太多了。方法多也试过了不知怎么,反正不行。最终自己想办法给解决了。当然首先还是要有fla源码。直接去管网就可以下载。[url]http://www.uploadify.com/wp-content/uploads/uploadify-v2.1.4...

戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)_vmware-vcsa-all-6.7.0-8169922.iso-程序员宅基地

文章浏览阅读9.6k次,点赞5次,收藏36次。戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)一、前期准备1、下载镜像下载esxi6.7镜像:VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso这里推荐到戴尔官网下载,Baidu搜索“戴尔驱动下载”,选择进入官网,根据提示输入服务器型号搜索适用于该型号服务器的所有驱动下一步选择具体类型的驱动选择一项下载即可待下载完成后打开软碟通(UItraISO),在“文件”选项中打开刚才下载好的镜像文件然后选择启动_vmware-vcsa-all-6.7.0-8169922.iso

推荐文章

热门文章

相关标签