- 浏览: 695637 次
- 性别:
- 来自: 长沙
文章分类
- 全部博客 (364)
- quick start (57)
- bboss aop (43)
- bboss mvc (48)
- bboss persistent (96)
- bboss taglib (30)
- bboss event (10)
- bbossgroups (52)
- bboss (32)
- bboss会话共享 (17)
- bboss rpc (7)
- bboss 国际化 (5)
- bboss 序列化 (9)
- bboss cxf webservice (8)
- bboss hessian (3)
- bboss 安全认证SSO (15)
- bboss 工作流 (6)
- 平台 (18)
- bboss quartz (3)
- 杂谈 (5)
- 大数据 (1)
- bboss elastic (24)
- bboss http (1)
- bboss kafka (1)
- Elasticsearch Scroll和Slice Scroll查询API使用案例 (1)
最新评论
-
qianhao123:
...
采用gradle构建和发布bboss方法介绍 -
qianhao123:
[img][/img]
采用gradle构建和发布bboss方法介绍 -
yin_bp:
欢迎大家参与working
高性能elasticsearch ORM开发库使用介绍 -
qq641879434:
万分感谢
bboss 持久层sql xml配置文件编写和加载方法介绍 -
yin_bp:
qq641879434 写道怎么设置配置文件 可以查看执行的S ...
bboss 持久层sql xml配置文件编写和加载方法介绍
bboss 动态令牌机制轻松搞定表单重复提交和请求校验签名单点登录,本文详细介绍之。
最新代码请参考文档获取:
bbossgroups 项目下载地址
一、概述
bboss在安全方面下了不少功夫,为了解决表单重复提交问题提供了动态令牌机制,具体内容如下:
1.增加动态令牌检测过滤器(可独立使用,也可与安全认证过滤器结合使用)
2.增加dtoken标签(用来在表单或者请求中投放动态令牌)
3.增加assertdtoken标签(用来在接收请求的服务器jsp页面头部判断客户端是否正确传递令牌,并检测令牌是否有效,如果没有令牌或者令牌无效,那么拒绝客户端请求)
4.assertdtoken注解(用来在接收请求的服务器mvc控制器方法执行前判断客户端是否正确传递令牌,并检测令牌是否有效,如果没有令牌或者令牌无效,那么拒绝客户端请求)
5.assertticket注解,通过ticket实现系统中sso时,添加了该注解的mvc请求方法要求客户端必须传递ticket参数
令牌的过滤器的详细配置请参考web.xml文件:
/bboss-mvc/WebRoot/WEB-INF/web.xml
令牌过滤器独立使用配置示例)
令牌服务配置文件tokenconf.xml:
/bboss-security/resources/tokenconf.xml
提供三种类型的动态令牌:
1.临时令牌(一次有效)
2.带应用和用户认证签名ticket的临时令牌(一次性有效)
3.带应用和用户认证签名ticket的有效期令牌(指定的时间内有效)
动态令牌机制可以有效解决以下问题:
1.防止表单重复提交
2.请求校验签名及单点登录功能
动态令牌提供了三种存储机制:
1.本地内存存储
2.数据库存储
3.mongodb存储
存储机制是以插件的模式存在,可以自行扩展实现基于redios和memcache的分布式存储机制。数据库令牌存储机制sql脚本:
/bboss-security/src-token/org/frameworkset/web/token/token.sql
bboss动态令牌可以在单机模式下使用,也可以在集群环境下使用。集群环境使用时,令牌必须使用数据库存储或者mongodb存储。
本文介绍防止表单重复提交功能,该功能只需要使用临时令牌即可。基于后面两种签名令牌实现请求校验签名及单点登录功能。
二、过滤器组件
我们通过web.xml中配置的令牌过滤器来拦截需要做令牌检测的url请求,过滤器组件如下:
1.org.frameworkset.web.token.TokenFilter(单独使用的令牌过滤器)
TokenFilter配置示例如下:
令牌管理配置文件tokenconf.xml:
令牌服务器配置文件
参数说明:
tokenfailpath-指定动态令牌校验失败跳转地址,如果没有指定直接响应403错误
tokenstore-指定令牌存储机制,目前提供两种机制:
mem:将令牌直接存储在内存空间中
mongodb:将令牌存储在mongodb中
db:将令牌存储在db中
ticketdualtime-应用ticket有效时间,必须和web session的有效期保持一致,获取比session会话时间要长,用于签名token的获取,在用户登录应用时申请一个与登录用户关联的ticket。
temptokenlivetime- 临时令牌和签名临时令牌在系统中的存活时间,默认为1小时,超过指定的时间,系统将自动清除超时的令牌,如果指定为-1将不检测, 单位为毫秒, session中的令牌不受影响
dualtokenlivetime-有效期令牌存活时间,超过该时间的有效期签名令牌将被系统自动回收。
tokenscaninterval-指定令牌超时检测时间间隔 单位为毫秒 默认为30分钟,如果需要检测,那么只要令牌持续时间超过tokendualtime 对应的令牌将会被清除,session中的令牌不受影响。
tokenStoreService-令牌存储服务,在其中注入了validateApplication服务,这个校验插件可以在申请令牌和ticket时对应用key和secret进行有效性校验,校验组件必须实现接口:
ALGORITHM-临时签名令牌和有效期签名令牌加密机制,默认为RSA,非对称加密算法,也可以采用ECC非对称加密算法。
令牌客户端配置文件tokenconf.xml
如果几个应用系统采用统一的令牌服务器时,则应用系统只需要进行客户端的配置即可:
应用系统通过hessian服务http://localhost:8081/bboss-mvc/hessian?service=tokenStoreService&container=tokenconf.xml获取令牌和校验令牌。
2.org.frameworkset.web.interceptor.AuthenticateFilter(抽象安全认证过滤器,是TokenFilter的子类,所有安全认证过滤器的实现类只需要配置令牌管理的相关参数既可以实现动态令牌机制),具体的配置示例如下:
令牌存储mongodb服务器连接配置文件:
/bboss-security/resources/mongodb.xml
根据mongodb的部署模式有两种配置方式:集群模式和单机模式
集群配置文件:
单mongodb服务器配置:
三、dtoken标签
有了令牌过滤器后,我们就需要在在客户端生成动态令牌,并将其放置在:
1.表单中input hidden元素中
2.url的参数串中
3.ajax请求的json参数中
这些都可以通过dtoken标签来实现,dtoken定义在pager-taglib.tld文件中,三种方式分别举例说明如下:
1.表单中input hidden元素中
<pg:dtoken/>标签将生成一个隐藏的动态令牌参数,将随着表单的提交而提交,该令牌只在本次请求中有效,不能被重复使用,这样就达到了解决了表单重复提交和跨站攻击的问题。
2.url的参数串中
<a href="/aaa/xxx.page?<pg:dtoken element='param'/>"
通过element='param'指定令牌以参数名=令牌的方式追加在url的参数中,随着url一起提交。该令牌只在本次url请求中有效,不能被重复使用,这样就达到了解决了表单重复提交和跨站攻击的问题。
3.ajax请求的json参数中
$("#queryresult").load("sayHelloEnums.page",{sex:$("#sex").val(),<pg:dtoken element="json"/>});
通过element=="json"指定令牌以参数名:令牌的json参数格式追加在ajax参数中,随着ajax请求一起被提交。该令牌只在本次ajax请求中有效,不能被重复使用,这样就达到了解决了表单重复提交和跨站攻击的问题。
四、assertdtoken标签和assertdtoken注解
通过上述三种方式能够有效地防止表单重复提交,但是能不能有效地防止跨站攻击呢,答案是不能,因为服务端在校验令牌时,首先检测有没有令牌被提交过来,如果没有则忽略令牌检查,认为请求是合法的,这样黑客可以根据该规则尝试将令牌参数从请求参数中去除来达到攻击的目的。为了防止这个漏洞,我们需要借助于assertdtoken标签和assertdtoken注解在服务器端强制要求令牌参数。
assertdtoken标签主要用于接收请求的jsp页面头部,例如:
<%@ taglib uri="/WEB-INF/pager-taglib.tld" prefix="pg"%>
<pg:assertdtoken/>
只有assertdtoken检测到令牌并且令牌合法,才执行后续的处理操作,否则直接跳转到过滤器参数tokenfailpath对应的地址或者抛出403异常。
assertdtoken注解用在bboss mvc控制器方法上,用来标注mvc控制器方法强制要求进行动态令牌校验,只有检测到令牌并且令牌合法,才继续开始执行控制器方法,否则直接跳转到过滤器参数tokenfailpath对应的地址或者抛出403异常。
assertdtoken注解使用实例:
五、生成令牌的java方法
组件接口:org.frameworkset.web.token.TokenService
组件支持调用模式:hessian模式,webservice服务模式,http服务模式(后续章节详细介绍)
令牌组件提供了以下接口方法:
具体的使用方法为:
令牌校验接口实例-令牌校验服务:
动态令牌机制可以有效解决以下问题:
1.防止表单重复提交
2.请求校验签名及单点登录功能。
六.ticket和签名令牌获取方法
下面介绍一下ticket和token获取的三种方法(hessian,webservice,http)
参数准备:
String appid = "appid";
String secret = "xxxxxxxxxxxxxxxxxxxxxx";
String account = "yinbp";
String worknumber = "10006673";
hessian
webservice
http:
客户端获取令牌服务组件- http服务方式申请token
令牌校验服务和令牌申请服务类似这里不做进一步介绍。
七.ticket实现sso
org.frameworkset.web.token.ws.TokenService //获取ticket组件
获取ticket服务webservice地址:
http://10.0.15.223/BbossToken/cxfservices/tokenService?wsdl
获取ticket服务hessian地址:
http://10.0.15.223/BbossToken/hessian?service=tokenService
org.frameworkset.web.token.ws.CheckTokenService//校验服务组件
校验服务webservice地址:
http://10.0.15.222/BbossToken/cxfservices/checktokenService?wsdl
校验服务hessian地址:
http://10.0.15.223/BbossToken/hessian?service=checktokenService
两步实现ticketsso :
第一步 来源应用系统登录时使用appid,appsecret,userAccount(账号),userWorknumber(工号)向令牌服务器申请ticket并保存到本地缓存中
第二步,使用ticket访问目标系统,将ticket作为参数传递给目标系统,目标系统请求过滤器拦截到ticket参数,拿到目标系统存储的appid和secret信息,与ticket一起到令牌服务器校验ticket的合法性,如果appid和secret校验合法,并且ticket也合法,则返回用户身份信息(账号和工号)给目标应用系统。
源系统通过ticket单点访问第三方系统url实例:
http://aa.com.cn/myapp/test.page?_dt_ticket_= + ticket ;
目标系统校验ticket并获取sso的用户信息方法:
tokenCheckResponse.getResultcode()得到的值为"ok"时表示ticket校验成功,否则返回的就是具体的错误码。
八、bboss动态令牌实现原理总结
bboss动态令牌机制采用动态令牌和session相结合的方式产生客户端令牌,一次请求产生一个唯一令牌,令牌识别采用客户端令牌和服务端session标识混合的方式进行判别,如果客户端令牌和服务端令牌正确匹配,则允许访问,否则认为用户为非法用户并阻止用户访问并跳转到tokenfailpath参数对应的地址,默认为空(直接响应403)。
令牌存储机制通过参数tokenstore指定,包括两种,内存存储和session存储,默认为session存储,当令牌失效(匹配后立即失效,或者超时失效)后,系统自动清除失效的令牌;采用session方式存储令牌时,如果客户端页面没有启用session,那么令牌还是会存储在内存中。
令牌生命周期:客户端的令牌在服务器端留有存根,当令牌失效(匹配后立即失效,或者超时失效)后,系统自动清除失效的令牌;当客户端并没有正确提交请求,会导致服务端令牌存根变为垃圾令牌,需要定时清除这些 垃圾令牌;如果令牌存储在session中,那么令牌的生命周期和session的生命周期保持一致,无需额外清除机制;如果令牌存储在内存中,那么令牌的清除由令牌管理组件自己定时扫描清除,定时扫描时间间隔由tokenscaninterval参数指定,单位为毫秒,默认为30分钟,存根保存时间由tokendualtime参数指定,默认为1个小时。
可以通过enableToken参数配置指定是否启用令牌检测机制,true检测,false不检测,默认为false不检测。
最后再总结一下:
1.tokenFilter拦截需要进行令牌校验客户端请求并执行校验逻辑、同时管理令牌的生命周期和提供定时清楚垃圾令牌机制
2.dtoken标签在客户端表单、url请求和ajax请求中投放动态令牌,仅仅在客户端放置动态随机令牌,可有效防止表单重复提交问题,但是不能彻底解决跨站攻击问题(因为狡猾的黑客会想尽办法去除令牌,绕过服务端令牌校验机制,从而达成跨站攻击目标),那么我们需要assertdtoken标签和assertdtoken注解来防止这种欺骗行为。
3.assertdtoken标签在接收请求的服务器jsp页面头部判断客户端是否正确传递令牌,并检测令牌是否有效,如果没有令牌或者令牌无效,那么拒绝客户端请求
4.assertdtoken注解在接收请求的服务器mvc控制器方法执行前判断客户端是否正确传递令牌,并检测令牌是否有效,如果没有令牌或者令牌无效,那么拒绝客户端请求
最新代码请参考文档获取:
bbossgroups 项目下载地址
一、概述
bboss在安全方面下了不少功夫,为了解决表单重复提交问题提供了动态令牌机制,具体内容如下:
1.增加动态令牌检测过滤器(可独立使用,也可与安全认证过滤器结合使用)
2.增加dtoken标签(用来在表单或者请求中投放动态令牌)
3.增加assertdtoken标签(用来在接收请求的服务器jsp页面头部判断客户端是否正确传递令牌,并检测令牌是否有效,如果没有令牌或者令牌无效,那么拒绝客户端请求)
4.assertdtoken注解(用来在接收请求的服务器mvc控制器方法执行前判断客户端是否正确传递令牌,并检测令牌是否有效,如果没有令牌或者令牌无效,那么拒绝客户端请求)
5.assertticket注解,通过ticket实现系统中sso时,添加了该注解的mvc请求方法要求客户端必须传递ticket参数
令牌的过滤器的详细配置请参考web.xml文件:
/bboss-mvc/WebRoot/WEB-INF/web.xml
令牌过滤器独立使用配置示例)
令牌服务配置文件tokenconf.xml:
/bboss-security/resources/tokenconf.xml
提供三种类型的动态令牌:
1.临时令牌(一次有效)
2.带应用和用户认证签名ticket的临时令牌(一次性有效)
3.带应用和用户认证签名ticket的有效期令牌(指定的时间内有效)
动态令牌机制可以有效解决以下问题:
1.防止表单重复提交
2.请求校验签名及单点登录功能
动态令牌提供了三种存储机制:
1.本地内存存储
2.数据库存储
3.mongodb存储
存储机制是以插件的模式存在,可以自行扩展实现基于redios和memcache的分布式存储机制。数据库令牌存储机制sql脚本:
/bboss-security/src-token/org/frameworkset/web/token/token.sql
bboss动态令牌可以在单机模式下使用,也可以在集群环境下使用。集群环境使用时,令牌必须使用数据库存储或者mongodb存储。
本文介绍防止表单重复提交功能,该功能只需要使用临时令牌即可。基于后面两种签名令牌实现请求校验签名及单点登录功能。
二、过滤器组件
我们通过web.xml中配置的令牌过滤器来拦截需要做令牌检测的url请求,过滤器组件如下:
1.org.frameworkset.web.token.TokenFilter(单独使用的令牌过滤器)
TokenFilter配置示例如下:
<filter> <filter-name>tokenFilter</filter-name> <filter-class>org.frameworkset.web.token.TokenFilter</filter-class> </init-param> <!-- 防止跨站请求过滤器相关参数结束 --> </filter> <filter-mapping> <filter-name>tokenFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>tokenFilter</filter-name> <url-pattern>*.page</url-pattern> </filter-mapping>
令牌管理配置文件tokenconf.xml:
令牌服务器配置文件
<properties> <!-- 令牌服务配置--> <property name="token.TokenService" class="org.frameworkset.web.token.TokenService" destroy-method="destroy"> <property name="ticketdualtime" value="172800000"/> <property name="temptokenlivetime" value="3600000"/> <property name="dualtokenlivetime" value="2592000000"/> <property name="tokenscaninterval" value="1800000"/> <property name="tokenstore" refid="attr:tokenStoreService"/> <!-- <property name="tokenstore" value="mem"/>--> <!-- <property name="tokenstore" value="mongodb|org.frameworkset.web.token.MongodbTokenStore"/> <property name="tokenstore" value="db|org.frameworkset.web.token.DBTokenStore"/> <property name="tokenstore" value="mem|org.frameworkset.web.token.MemTokenStore"/>--> <property name="enableToken" value="true"/> <!-- <property name="ALGORITHM" value="RSA"/> --> <property name="tokenfailpath" value="/common/jsp/tokenfail.jsp"/> </property> <property name="tokenStoreService" class="org.frameworkset.web.token.MongodbTokenStore"> <property name="validateApplication" class="com.xxx.application.service.impl.SYSValidationApplication"/> </property> </properties>
参数说明:
tokenfailpath-指定动态令牌校验失败跳转地址,如果没有指定直接响应403错误
tokenstore-指定令牌存储机制,目前提供两种机制:
mem:将令牌直接存储在内存空间中
mongodb:将令牌存储在mongodb中
db:将令牌存储在db中
ticketdualtime-应用ticket有效时间,必须和web session的有效期保持一致,获取比session会话时间要长,用于签名token的获取,在用户登录应用时申请一个与登录用户关联的ticket。
temptokenlivetime- 临时令牌和签名临时令牌在系统中的存活时间,默认为1小时,超过指定的时间,系统将自动清除超时的令牌,如果指定为-1将不检测, 单位为毫秒, session中的令牌不受影响
dualtokenlivetime-有效期令牌存活时间,超过该时间的有效期签名令牌将被系统自动回收。
tokenscaninterval-指定令牌超时检测时间间隔 单位为毫秒 默认为30分钟,如果需要检测,那么只要令牌持续时间超过tokendualtime 对应的令牌将会被清除,session中的令牌不受影响。
tokenStoreService-令牌存储服务,在其中注入了validateApplication服务,这个校验插件可以在申请令牌和ticket时对应用key和secret进行有效性校验,校验组件必须实现接口:
org.frameworkset.web.token.ValidateApplication public interface ValidateApplication { public boolean checkApp(String appid,String secret) throws TokenException; }
ALGORITHM-临时签名令牌和有效期签名令牌加密机制,默认为RSA,非对称加密算法,也可以采用ECC非对称加密算法。
令牌客户端配置文件tokenconf.xml
如果几个应用系统采用统一的令牌服务器时,则应用系统只需要进行客户端的配置即可:
<!-- 令牌服务配置--> <property name="token.TokenService" class="org.frameworkset.web.token.TokenService" > <property name="tokenstore" factory-class="com.caucho.hessian.client.HessianProxyFactory" factory-method="create"> <construction> <property value="org.frameworkset.web.token.TokenStore"/> <property> <![CDATA[http://localhost:8081/bboss-mvc/hessian?service=tokenStoreService&container=tokenconf.xml]]> </property> </construction> </property> <property name="client" value="true"/> <property name="appid" value="tas"/> <property name="secret" value="2d66d96f-ada4-4e12-a4e4-f4541c0b4bea"/> <property name="enableToken" value="true"/> <!-- 指定动态令牌校验失败跳转地址 如果没有指定直接采用redirecturl对应的地址作为跳转地址 --> <property name="tokenfailpath" value="/common/jsp/tokenfail.jsp"/> </property>
应用系统通过hessian服务http://localhost:8081/bboss-mvc/hessian?service=tokenStoreService&container=tokenconf.xml获取令牌和校验令牌。
2.org.frameworkset.web.interceptor.AuthenticateFilter(抽象安全认证过滤器,是TokenFilter的子类,所有安全认证过滤器的实现类只需要配置令牌管理的相关参数既可以实现动态令牌机制),具体的配置示例如下:
<filter> <filter-name>securityFilter</filter-name> <filter-class>org.frameworkset.web.interceptor.MyFirstAuthFilter</filter-class> 。。。。。。。 </filter> <filter-mapping> <filter-name>securityFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>securityFilter</filter-name> <url-pattern>*.page</url-pattern> </filter-mapping>
令牌存储mongodb服务器连接配置文件:
/bboss-security/resources/mongodb.xml
根据mongodb的部署模式有两种配置方式:集群模式和单机模式
集群配置文件:
<properties> <!-- 增加mongodb数据源配置和client工厂类 --> <property name="default" factory-class="org.frameworkset.nosql.mongodb.MongoDB" init-method="init" destroy-method="close" factory-method="getMongoClient"> <property name="serverAddresses" > 10.0.15.134:27017 10.0.15.134:27018 10.0.15.38:27017 10.0.15.39:27017 </property> <property name="option" > QUERYOPTION_SLAVEOK </property> <property name="writeConcern" value="JOURNAL_SAFE"/> <property name="readPreference" value="NEAREST"/> </property> </properties>
单mongodb服务器配置:
<properties> <!-- 增加mongodb数据源配置和client工厂类 --> <property name="default" factory-class="org.frameworkset.nosql.mongodb.MongoDB" init-method="init" destroy-method="close" factory-method="getMongoClient"> <property name="serverAddresses" > 192.168.1.100:27016 </property> <property name="option" ></property> <property name="writeConcern" value="JOURNAL_SAFE"/> <property name="readPreference" value=""/> </property> </properties>
三、dtoken标签
有了令牌过滤器后,我们就需要在在客户端生成动态令牌,并将其放置在:
1.表单中input hidden元素中
2.url的参数串中
3.ajax请求的json参数中
这些都可以通过dtoken标签来实现,dtoken定义在pager-taglib.tld文件中,三种方式分别举例说明如下:
1.表单中input hidden元素中
<form action="sayHelloNumber.page" method="post"> <pg:dtoken/> <table cellspacing="0" > <tbody> <tr><td> 请输入您的幸运数字: <input name="name" type="text"> </td> </tr> <tr> <td> 来自服务器的问候: aa</td> </tr> <tr> <td><input type="submit" name="确定" value="确定"></td> </tr> </tbody> </table></form>
<pg:dtoken/>标签将生成一个隐藏的动态令牌参数,将随着表单的提交而提交,该令牌只在本次请求中有效,不能被重复使用,这样就达到了解决了表单重复提交和跨站攻击的问题。
2.url的参数串中
<a href="/aaa/xxx.page?<pg:dtoken element='param'/>"
通过element='param'指定令牌以参数名=令牌的方式追加在url的参数中,随着url一起提交。该令牌只在本次url请求中有效,不能被重复使用,这样就达到了解决了表单重复提交和跨站攻击的问题。
3.ajax请求的json参数中
$("#queryresult").load("sayHelloEnums.page",{sex:$("#sex").val(),<pg:dtoken element="json"/>});
通过element=="json"指定令牌以参数名:令牌的json参数格式追加在ajax参数中,随着ajax请求一起被提交。该令牌只在本次ajax请求中有效,不能被重复使用,这样就达到了解决了表单重复提交和跨站攻击的问题。
四、assertdtoken标签和assertdtoken注解
通过上述三种方式能够有效地防止表单重复提交,但是能不能有效地防止跨站攻击呢,答案是不能,因为服务端在校验令牌时,首先检测有没有令牌被提交过来,如果没有则忽略令牌检查,认为请求是合法的,这样黑客可以根据该规则尝试将令牌参数从请求参数中去除来达到攻击的目的。为了防止这个漏洞,我们需要借助于assertdtoken标签和assertdtoken注解在服务器端强制要求令牌参数。
assertdtoken标签主要用于接收请求的jsp页面头部,例如:
<%@ taglib uri="/WEB-INF/pager-taglib.tld" prefix="pg"%>
<pg:assertdtoken/>
只有assertdtoken检测到令牌并且令牌合法,才执行后续的处理操作,否则直接跳转到过滤器参数tokenfailpath对应的地址或者抛出403异常。
assertdtoken注解用在bboss mvc控制器方法上,用来标注mvc控制器方法强制要求进行动态令牌校验,只有检测到令牌并且令牌合法,才继续开始执行控制器方法,否则直接跳转到过滤器参数tokenfailpath对应的地址或者抛出403异常。
assertdtoken注解使用实例:
@AssertDToken public String sayHelloNumber(@RequestParam(name = "name") int ynum, ModelMap model) { if (ynum != 0) { model.addAttribute("serverHelloNumber", "幸运数字为[" + ynum + "]!"); } else model.addAttribute("serverHelloNumber", "幸运数字为[" + ynum + "]!,好像有点不对哦。"); return "path:sayHello"; }
五、生成令牌的java方法
组件接口:org.frameworkset.web.token.TokenService
组件支持调用模式:hessian模式,webservice服务模式,http服务模式(后续章节详细介绍)
令牌组件提供了以下接口方法:
public abstract String genToken(ServletRequest request, String fid, boolean cache) throws TokenException; public abstract String buildDToken(String elementType, HttpServletRequest request) throws TokenException; public abstract String buildDToken(String elementType, String jsonsplit, HttpServletRequest request, String fid) throws TokenException; /** * 生成隐藏域令牌,输出值为: * <input type="hidden" name="_dt_token_" value="-1518435257"> * @param request * @return * @throws TokenException */ public abstract String buildHiddenDToken(HttpServletRequest request) throws TokenException; /** * 生成json串令牌 * 如果jsonsplit为',则输出值为: * _dt_token_:'1518435257' * 如果如果jsonsplit为",则输出值为: * _dt_token_:"1518435257" * @param jsonsplit * @param request * @return * @throws TokenException */ public abstract String buildJsonDToken(String jsonsplit, HttpServletRequest request) throws TokenException; /** * 生成url参数串令牌 * 输出值为: * _dt_token_=1518435257 * @param request * @return * @throws TokenException */ public abstract String buildParameterDToken(HttpServletRequest request) throws TokenException; /** * 只生成令牌,对于这种方式,客户端必须将该token以参数名_dt_token_传回服务端,否则不起作用 * 输出值为: * 1518435257 * @param request * @return * @throws TokenException */ public abstract String buildDToken(HttpServletRequest request) throws TokenException; public abstract String buildDToken(String elementType, String jsonsplit, HttpServletRequest request, String fid, boolean cache) throws TokenException; public abstract String genDualTokenWithDefaultLiveTime(String appid, String secret, String ticket) throws Exception; public abstract String genTicket(String account, String worknumber, String appid, String secret) throws TokenException; public abstract boolean isEnableToken(); 获取带认证的临时一次性令牌-返回的token包含令牌和用户账号信息 public String genAuthTempToken( String appid,//应用标识 String secret,//应用口令 String ticket) //访问票据-用于单点登录 throws Exception; 获取带认证的有效期令牌-返回的token包含令牌和用户账号信息 public String genDualToken( String appid, //应用标识 String secret, //应用口令 String ticket,//访问票据-用于单点登录 long dualtime) 令牌有效时间 throws Exception; 获取给应用颁发的公钥 public String getPublicKey( String appid, //应用标识 String secret) //应用口令 throws Exception; 获取一次性的临时令牌 public String genTempToken() throws Exception;
具体的使用方法为:
@WebService(name="TokenService",targetNamespace="com.sany.common.action.TokenService") public class TokenController implements TokenService { /** * 获取令牌请求 * @param request * @return * @throws TokenException */ public @ResponseBody String getToken(HttpServletRequest request) throws TokenException { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { return TokenHelper.getTokenService().buildDToken(request); } else { return null; } } public @ResponseBody String genTempToken() throws Exception { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { return TokenHelper.getTokenService().genTempToken(); } else { return null; } } /** * 获取令牌请求 * @param request * @return * @throws Exception */ public @ResponseBody String genAuthTempToken(String appid,String secret,String ticket) throws Exception { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { return TokenHelper.getTokenService().genAuthTempToken(appid, secret, ticket); } else { return null; } } /** * 获取令牌请求 * @param request * @return * @throws Exception */ public @ResponseBody String genDualToken(String appid,String secret,String ticket) throws Exception { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { long dualtime = 30l*24l*60l*60l*1000l; return TokenHelper.getTokenService().genDualToken(appid, secret, ticket,dualtime); } else { return null; } } /** * 获取令牌请求 * @param request * @return * @throws Exception */ public @ResponseBody String genDualTokenWithDefaultLiveTime(String appid,String secret,String ticket) throws Exception { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { return TokenHelper.getTokenService().genDualTokenWithDefaultLiveTime(appid, secret, ticket); } else { return null; } } /** * 获取应用公钥 * @param appid * @param secret * @return * @throws Exception */ public @ResponseBody String getPublicKey(String appid,String secret) throws Exception { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { return TokenHelper.getTokenService().getPublicKey(appid, secret); } else { return null; } } /** * 获取令牌请求 * http://localhost:8081/SanyPDP/token/getParameterToken.freepage * @param request * @return * @throws TokenException */ public @ResponseBody String getParameterToken(HttpServletRequest request) throws TokenException { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { return TokenHelper.getTokenService().buildParameterDToken(request); } else { return null; } } public @ResponseBody String genTicket(String account,String worknumber,String appid,String secret) throws TokenException { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { return TokenHelper.getTokenService().genTicket( account, worknumber, appid, secret); } else { return null; } } }
令牌校验接口实例-令牌校验服务:
@WebService(name="CheckTokenService",targetNamespace="com.sany.common.action.CheckTokenService") public class CheckTokenContoller implements CheckTokenService{ public @ResponseBody(datatype="json") TokenResult checkToken(String appid,String secret,String token) throws TokenException { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { return TokenHelper.getTokenService().checkToken(appid,secret,token); } else { return null; } } public @ResponseBody Integer checkTempToken(String token) throws TokenException { if(TokenHelper.isEnableToken())//如果开启令牌机制就会存在memTokenManager对象,否则不存在 { return TokenHelper.getTokenService().checkTempToken(token); } else { return TokenStore.token_request_validateresult_notenabletoken; } } }
动态令牌机制可以有效解决以下问题:
1.防止表单重复提交
2.请求校验签名及单点登录功能。
六.ticket和签名令牌获取方法
下面介绍一下ticket和token获取的三种方法(hessian,webservice,http)
参数准备:
String appid = "appid";
String secret = "xxxxxxxxxxxxxxxxxxxxxx";
String account = "yinbp";
String worknumber = "10006673";
hessian
客户端获取令牌服务组件- hessian服务方式申请token //hessian服务方式申请token HessianProxyFactory factory = new HessianProxyFactory(); //String url = "http://localhost:8081/context/hessian?service=tokenService"; String url = "http://localhost:8081/SanyPDP/hessian?service=tokenService"; TokenService tokenService = (TokenService) factory.create(TokenService.class, url); //通过hessian根据账号或者工号获取ticket String ticket = tokenService.genTicket(account, worknumber, appid, secret); String token = tokenService.genAuthTempToken(appid, secret, ticket);
webservice
客户端获取令牌服务组件- webservice服务方式申请token url = "http://localhost:8081/SanyPDP/cxfservices/tokenService"; JaxWsProxyFactoryBean WSServiceClientFactory = new JaxWsProxyFactoryBean(); WSServiceClientFactory.setAddress(url); WSServiceClientFactory.setServiceClass(TokenService.class); tokenService = (TokenService)WSServiceClientFactory.create(); //通过webservice根据账号或者工号获取ticket //String ticket = tokenService.genTicket(account, worknumber, appid, secret); token = tokenService.genAuthTempToken(appid, secret, ticket);
http:
客户端获取令牌服务组件- http服务方式申请token
url = "http://localhost:8081/SanyPDP/token/genAuthTempToken.freepage?appid="+appid + "&secret="+secret + "&ticket="+ticket; //url = "http://10.25.192.142:8081/SanyPDP/token/genDualToken.freepage?appid="+appid + "&secret="+secret + "&account="+account; token = org.frameworkset.spi.remote.http.HttpReqeust.httpPostforString(url); //通过http根据账号或者工号获取ticket //url = "http://10.25.192.142:8081/SanyPDP/token/genTicket.freepage?appid="+appid + "&secret="+secret + "&account="+account + "&worknumber="+worknumber; //String ticket = = org.frameworkset.spi.remote.http.HttpReqeust.httpPostforString(url);
令牌校验服务和令牌申请服务类似这里不做进一步介绍。
七.ticket实现sso
org.frameworkset.web.token.ws.TokenService //获取ticket组件
获取ticket服务webservice地址:
http://10.0.15.223/BbossToken/cxfservices/tokenService?wsdl
获取ticket服务hessian地址:
http://10.0.15.223/BbossToken/hessian?service=tokenService
org.frameworkset.web.token.ws.CheckTokenService//校验服务组件
校验服务webservice地址:
http://10.0.15.222/BbossToken/cxfservices/checktokenService?wsdl
校验服务hessian地址:
http://10.0.15.223/BbossToken/hessian?service=checktokenService
两步实现ticketsso :
第一步 来源应用系统登录时使用appid,appsecret,userAccount(账号),userWorknumber(工号)向令牌服务器申请ticket并保存到本地缓存中
String appid = "tas"; String secret = "2d66d96f-ada4-4e12-a4e4-f4541c0b4bea"; String account = "marc";//如果使用工号则loginType为2,否则为1 String worknumber = "10006857"; HessianProxyFactory factory = new HessianProxyFactory(); String url = "http://10.0.15.223/SanyToken/hessian?service=tokenService";//令牌服务器获取ticket服务地址 TokenService tokenService = (TokenService) factory.create(TokenService.class, url); //通过hessian根据账号或者工号获取ticket String ticket = tokenService.genTicket(account, worknumber, appid, secret);
第二步,使用ticket访问目标系统,将ticket作为参数传递给目标系统,目标系统请求过滤器拦截到ticket参数,拿到目标系统存储的appid和secret信息,与ticket一起到令牌服务器校验ticket的合法性,如果appid和secret校验合法,并且ticket也合法,则返回用户身份信息(账号和工号)给目标应用系统。
源系统通过ticket单点访问第三方系统url实例:
http://aa.com.cn/myapp/test.page?_dt_ticket_= + ticket ;
目标系统校验ticket并获取sso的用户信息方法:
HessianProxyFactory factory = new HessianProxyFactory(); String url = "http://10.0.15.223/BbossToken/hessian?service=checktokenService";//令牌服务器校验ticket服务地址 org.frameworkset.web.token.ws.CheckTokenService checkTokenService = (CheckTokenService) factory.create(org.frameworkset.web.token.ws.CheckTokenService.class, url); org.frameworkset.web.token.ws.TokenCheckResponse tokenCheckResponse = checkTokenService.checkTicket(appid, secret, ticket); System.out.println(tokenCheckResponse.getResultcode()); System.out.println(tokenCheckResponse.getUserAccount()); System.out.println(tokenCheckResponse.getWorknumber());
tokenCheckResponse.getResultcode()得到的值为"ok"时表示ticket校验成功,否则返回的就是具体的错误码。
八、bboss动态令牌实现原理总结
bboss动态令牌机制采用动态令牌和session相结合的方式产生客户端令牌,一次请求产生一个唯一令牌,令牌识别采用客户端令牌和服务端session标识混合的方式进行判别,如果客户端令牌和服务端令牌正确匹配,则允许访问,否则认为用户为非法用户并阻止用户访问并跳转到tokenfailpath参数对应的地址,默认为空(直接响应403)。
令牌存储机制通过参数tokenstore指定,包括两种,内存存储和session存储,默认为session存储,当令牌失效(匹配后立即失效,或者超时失效)后,系统自动清除失效的令牌;采用session方式存储令牌时,如果客户端页面没有启用session,那么令牌还是会存储在内存中。
令牌生命周期:客户端的令牌在服务器端留有存根,当令牌失效(匹配后立即失效,或者超时失效)后,系统自动清除失效的令牌;当客户端并没有正确提交请求,会导致服务端令牌存根变为垃圾令牌,需要定时清除这些 垃圾令牌;如果令牌存储在session中,那么令牌的生命周期和session的生命周期保持一致,无需额外清除机制;如果令牌存储在内存中,那么令牌的清除由令牌管理组件自己定时扫描清除,定时扫描时间间隔由tokenscaninterval参数指定,单位为毫秒,默认为30分钟,存根保存时间由tokendualtime参数指定,默认为1个小时。
可以通过enableToken参数配置指定是否启用令牌检测机制,true检测,false不检测,默认为false不检测。
最后再总结一下:
1.tokenFilter拦截需要进行令牌校验客户端请求并执行校验逻辑、同时管理令牌的生命周期和提供定时清楚垃圾令牌机制
2.dtoken标签在客户端表单、url请求和ajax请求中投放动态令牌,仅仅在客户端放置动态随机令牌,可有效防止表单重复提交问题,但是不能彻底解决跨站攻击问题(因为狡猾的黑客会想尽办法去除令牌,绕过服务端令牌校验机制,从而达成跨站攻击目标),那么我们需要assertdtoken标签和assertdtoken注解来防止这种欺骗行为。
3.assertdtoken标签在接收请求的服务器jsp页面头部判断客户端是否正确传递令牌,并检测令牌是否有效,如果没有令牌或者令牌无效,那么拒绝客户端请求
4.assertdtoken注解在接收请求的服务器mvc控制器方法执行前判断客户端是否正确传递令牌,并检测令牌是否有效,如果没有令牌或者令牌无效,那么拒绝客户端请求
发表评论
-
bboss mvc控制器方法跳转地址设置方法介绍
2017-12-09 21:52 911bboss mvc控制器方法跳转地址设置方法介绍 1.直接指 ... -
bboss mvc json插件设置日期类型格式方法
2017-02-28 11:33 746bboss mvc json插件设置日期类型格式方法 一般的 ... -
bboss mvc控制器实现etag和last modify两种http缓存机制
2016-09-07 23:48 1266bboss mvc控制器实现etag和last modify两 ... -
bboss wordpdf构建部署介绍
2016-09-02 15:47 571bboss wordpdf构建部署介绍 下载 源码下载地址: ... -
bboss 令牌和凭证redis存储机制配置
2016-03-29 20:42 1388bboss 提供了四种令牌和凭证存储机制: 内存 不能在集 ... -
bboss 票据实现系统SSO功能介绍
2016-03-10 16:50 1696测试环境应用账号: app ... -
解决tomcat stop报Illegal access: this web application instance has been stopped异常方法
2015-12-26 23:41 5949解决tomcat stop报Illegal access: t ... -
bboss mvc文件上传实例
2015-06-08 11:13 37本文着重介绍bboss mvc文件上传功能,切入正题 功能点 ... -
bboss mvc @RequestBody注解使用说明
2014-10-23 15:53 1050@RequestBody可以将客户端请求报文体通过数据类型转换 ... -
平台自定义资源权限控制使用方法
2014-10-23 11:17 1695本文以一个简单的实例来介绍bboss平台自定义资源权限控制使用 ... -
平台登录账号口令加密机制设置方法
2014-10-13 16:35 1146平台登录账号口令加密机制设置方法 平台加密机制: ... -
bboss安全认证过滤器认证后重定向到请求页面功能介绍
2014-10-12 10:55 1342本文介绍bboss安全认证 ... -
bboss mvc控制器方法响应报文注解ResponseBody使用说明
2014-09-20 22:39 1193bboss mvc控制器方法响应 ... -
bboss mvc启动事件监听器使用方法
2014-09-02 20:25 1158在实际应用,往往需要在mvc容器启动后执行相应的操作,bbos ... -
bboss跨站攻击白名单和脚本攻击防火墙配置
2014-08-01 09:56 1108本文详细介绍bboss跨站攻击白名单和跨站脚本攻击防火墙配置 ... -
bboss session共享使用方法介绍
2014-05-10 16:12 6146bboss session共享使用方法 ... -
bboss将一个组件同时发布为webservice,hessian,http三种服务方法介绍
2014-04-12 14:31 1657bboss将一个组件同时发布为webservice,hessi ... -
bboss发布apache cxf 2.7.6服务和定义客户端服务实例可能产生冲突解决办法
2014-03-22 23:16 1091bboss发布apache cxf 2.7.6服务和定义客户端 ... -
bboss mvc接收和响应xml格式数据的方法
2013-12-28 19:14 1072本文介绍bboss mvc接收和响应xml格式数据的方法 1 ... -
bboss防止跨站攻击策略
2013-10-12 21:35 1094bboss防止跨站攻击策略 此前博客中撰文介绍了bboss 动 ...
相关推荐
bboss会话共享是一种分布式会话管理技术,它针对在集群环境下应用部署时如何解决会话数据丢失和单点登录问题提供了专门的解决方案。根据提供的文档内容,我们可以详细探讨bboss会话共享涉及的关键知识点。 首先,...
BBoss MVCDemo提供了灵活的控制器机制,可以方便地处理HTTP请求,进行参数绑定、校验以及异常处理。 4. **AOP(面向切面编程)**:BBoss MVCDemo支持AOP,可以实现如事务管理、日志记录、权限控制等功能,提高代码...
BBoss安全认证过滤器是Java Web开发中一种用于实现用户身份验证和权限控制的重要组件。在Web应用程序中,过滤器(Filter)是Servlet规范的一部分,它允许开发者在请求到达目标Servlet或JSP之前进行预处理,以及在...
BBoss(全称为bbossgroups)是一个专为企业级J2EE应用设计的开源框架,它为Java开发者提供了一系列强大的工具和服务,以简化Web应用程序的开发过程。该框架旨在提高开发效率,降低维护成本,同时保持高度的灵活性和...
**Elasticsearch 开发环境搭建与 BBoss 入门教程** Elasticsearch 是一个高度可扩展的开源全文搜索引擎,设计用于快速提供近实时的搜索和分析能力。BBoss(Business Boss)是基于Elasticsearch的一个强大且灵活的...
展示了通过spring boot管理单集群功能和管理多集群功能 单集群测试用例:eshelloword-spring-boot-starter\src\test\java\org\bboss\elasticsearchtest\springboot\BBossESStarterTestCase.java 单集群演示功能...
**bboss-datatran** 是一个由 **bboss** 社区开源的高效数据处理工具,专注于数据采集、数据清洗转换以及数据入库等任务。它实现了流批一体化的数据处理能力,使得用户能够灵活地应对实时和批量的数据处理场景。在...
8. `cglib-nodep-3.1.jar`:CGLIB是一个代码生成库,常用于Java代理和动态类生成,可能在BBoss Elasticsearch中用于创建Elasticsearch操作的动态代理类。 通过这些库的组合,BBoss Elasticsearch提供了一种高效且...
【bboss-db-elasticsearch-tool-master_java_】是一个Java ORM(对象关系映射)框架,它在功能上超越了MyBatis,提供了对多种数据库的广泛支持,包括MySQL、Oracle、PostgreSQL、SQLServer、DB2、DM以及MongoDB。...
结合bboss和Elasticsearch,开发者可以轻松实现日志实时分析、用户行为追踪、商品推荐等业务场景,通过DSL实现复杂查询和聚合分析,提升应用的数据处理能力。 总之,bboss+es基本操作示例是学习和实践Elastic...
springboot集成ElasticsearchBboss调用Elasticsearch的案例分享
在IT行业中,数据库操作是必不可少的一部分,特别是在处理大数据量或者特殊数据类型如CLOB(Character Large Object)和BLOB(Binary Large Object)时。BBoss Persistent是一个轻量级的持久层框架,它提供了方便的...
bbosssession是一个用于集群环境中实现会话共享的解决方案,它提供了第四代集群会话管理的完整实现,与之前的会话管理方式相比,有着诸多优势和特点。本培训文档将介绍集群session管理的发展历史、bbosssession的...
BBoss和EasyUI是两个在IT领域中常用于构建企业级Web应用的开源框架。BBoss,全称为“Business Basic Operation Support”,是一个基于Java的企业级开发框架,它提供了丰富的组件和工具,使得开发者能够快速地进行...
本文将详细介绍如何在BBoss的IOC配置文件中引用外部属性文件,以便更好地管理和动态配置应用。 首先,BBoss的IOC配置文件通常是一个XML文件,比如`bboss-ioc.xml`,在这个文件中我们可以声明并配置各种bean。当需要...
官方版本,亲测可用
标题中的“bboss mvc 通过jsonp实现跨站跨域远程访问”指的是使用bboss MVC框架来处理JSONP(JSON with Padding)请求,以克服浏览器的同源策略限制,实现跨域数据交互。bboss MVC是一个Java Web开发框架,它提供了...
Elasticsearch rest client bboss介绍-Elastic2018中国开发者大会演讲稿