- 浏览: 299759 次
文章分类
最新评论
-
流年末年:
那四个参数还是没看懂.....能不能解释下showPassst ...
我写的密码强度验证方法(原创) -
kingcs2008:
// 验证pws.jsshowPassstrength(&qu ...
我写的密码强度验证方法(原创) -
h957355152:
请问博主这个怎么用呢?我直接放到jsp里面调用showPass ...
我写的密码强度验证方法(原创) -
qq_15138059:
我写的全国省市县三级联动菜单,拿出来和大家分享了(原创) -
valenon:
评论呢?从MAIL FROM命令开始貌似就出错了:500 Er ...
如何发送伪造的电子邮件
Remember me 是否安全?
对我们精心保护的站点来说,为了用户体验而添加的任何与安全相关的功能,都有增加安全风险的潜在可能。按照其默认方式, Remember me 功能存在用户的 cookie 被拦截并被恶意用户重用的风险。下图展现了这种情况是如何发生的:
使用 SSL (第四章进行讨论)以及其他的网络安全技术能缓解这种类型攻击的风险,但是要注意的是还有其他技术如跨站脚本攻击( XSS )能够窃取或损害一个 remembered user session 。为了照顾用户的易用性,我们不会愿意让用户的财产信息或个人信息因为 remembered session 的不合理使用而遭到篡改或窃取。
【尽管我们不会涉及恶意用户行为的细节,但是当你实现安全系统时,了解恶意用户所使用的攻击技术是很重要的。 XSS 是其中的一种技术,当然还有其他的很多种。强烈建议你了解 OWASP Top Ten ( http://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project )作为一个入门列表并参考一本 web 应用安全参考书,里面介绍了各种的技术使用。】
平衡用户易用性和应用安全性的一种通用方法是识别出站点中与个人或敏感信息相关的功能点。确保这些功能点在进行授权校验时不仅要判断用户的角色,还要保证用户进行了完整的用户名和密码认证。这可以通过使用 SpEL 表达式语言的 fullyAuthenticated 伪属性来实现,关于授权规则的 SpEL 表达式语言我们在第二章中已经有所介绍。
Remember me 认证与完整认证的在认证规则上的区别
我们将在随后的第五章:精确的访问控制 中介绍高级的认证技术,但是,了解能够辨别认证 session 是否为 remembered 并以此建立访问规则也是很重要的。
我们可以设想一个使用 remembered session 登录的用户要查看和修改他的“ wish list ”。这与其他的客户在线站点很类似,并不会出现与用户信息或财务信息相关的风险(要注意的是每个站点各不相同,不能盲目的将这些规则应用与你的站点)。相反的,我们将会重点保护用户的账号以及订单功能。我们要确保即使是 remembered 的用户,如果试图访问账号信息或定购产品,都需要对他们进行认证。以下为我们如何设置授权规则:
<intercept-url pattern="/login.do" access="permitAll"/>
- < intercept-url pattern = "/account/*.do"
- access = "hasRole('ROLE_USER') and fullyAuthenticated" />
- < intercept-url pattern = "/*" access = "hasRole('ROLE_USER')" />
已经存在的登录页和 ROLE_USER 设置没有变化。但我们添加了一条规则,要求用户具有 GrantedAuthority 的 ROLE_USER 角色同时还要求用户被完全的认证,即这个认证的 session 确实是通过提供用户名、密码或等同的凭证来进行认证的。注意这里的 SpEL 逻辑操作语法——在 SpEL 中,使用 and , or 以及 not 作为逻辑操作符。这是 SpEL 的设计者充分考虑的结果,因为 && 操作符在 XML 中很难被使用。
如果你在应用中尝试运行,如果以 remember me 功能登录并试图访问“ My Account ”链接,你将会得到一个 403 访问拒绝的提示,这说明这个地址已经被适当地保护了。出现错误界面是因为我们应用的配置还是使用默认的 AccessDeniedHandler ,这个类负责捕获和响应 AccessDeniedException 的信息。我们将会在第六章学习 AccessDeniedException 怎样被处理时,自定义这个行为。
【不使用表达式来实现完全认证的检查。如果你的应用不使用 SpEL 表达式来进行访问控制声明,你可以通过使用 IS_AUTHENTICATED_FULLY 访问规则来检查用户是不是进行了完整的认证(如: access=" IS_AUTHENTICATED_FULLY" )。但要注意的是,这种标准的角色设置声明并没有 SpEL 那样强的表现力,所以如果要处理复杂的 boolean 表达式的时候,可能会比较困难。】
错误处理尚没有添加,但是你可以看到通过这种方式将 remember me 的易用性与更高层次的安全性结合了起来,用户访问敏感的信息时就会被要求提供完整的凭证信息。
构建一个关联 IP 的 Remember me Service
有一种让 remember me 功能更安全的方式就是将用户的 IP 地址绑定到 cookie 的内容上。让我们通过一个例子来描述怎样构建 RememberMeServices 的实现类来完成这个功能。
基本的实现方式是扩展 o.s.s.web.authentication.rememberme.TokenBasedRememberMeServices 基类,以添加请求者的 IP 地址到 cookie 本身和其他的 MD5 哈希元素中。
扩展这个基类涉及到重写两个主要方法,并重写或实现几个小的帮助方法。还有一个要注意的是我们需要临时存储 HttpServletRequest (将使用它来得到用户的 IP 地址)到一个 ThreadLocal 中,因为基类中的一些方法并没有将 HttpServletRequest 作为一个参数。
扩展 TokenBasedRememberMeServices
首先,我们要扩展 TokenBasedRememberMeServices 类并重写父类的特定行为。尽管父类是非常易于重写,但是我们不想去重复一些重要的处理流程,所以能使这个类非常简明却有点不好理解。在 com.packtpub.springsecurity.security 包下创建这个类:
还有一些简单的方法来设置和获取 ThreadLocal HttpServletRequest :
- private static final ThreadLocal<HttpServletRequest> requestHolder =
- new ThreadLocal<HttpServletRequest>();
- public HttpServletRequest getContext() {
- return requestHolder.get();
- }
- public void setContext(HttpServletRequest context) {
- requestHolder.set(context);
- }
我们还需要添加一个工具方法以从 HttpServletRequest 中获取 IP 地址:
- protected String getUserIPAddress(HttpServletRequest request) {
- return request.getRemoteAddr();
- }
我们要重写的第一个有趣的方法是 onLoginSuccess ,它用来为 remember me 处理设置 cookie 的值。在这个方法中,我们需要设置 ThreadLocal 并在完成处理后将其清除。需要记住的是父类方法的处理流程——收集用户的所有认证请求信息并将其合成到 cookie 中。
- @Override
- public void onLoginSuccess(HttpServletRequest request,
- HttpServletResponse response,
- Authentication successfulAuthentication) {
- try
- {
- setContext(request);
- super .onLoginSuccess(request, response, successfulAuthentication
- }
- finally
- { setContext(null );
- }
- }
父类的 onLoginSuccess 方法将会触发 makeTokenSignature 方法来创建认证凭证的 MD5 哈希值。我们将要重写此方法,以实现从 request 中获取 IP 地址并使用 Spring 框架的一个工具类编码要返回的 cookie 值。(这个方法在进行 remember me 校验时还会被调用到,以判断前台传递过来的 cookie 值与后台根据用户名、密码、 IP 地址等信息生成的 MD5 值是否一致。——译者注)
- @Override
- protected String makeTokenSignature( long tokenExpiryTime,
- String username, String password) {
- return DigestUtils.md5DigestAsHex((username + ":" +
- tokenExpiryTime + ":" + password + ":" + getKey() + ":" + getUserIPAdd
- ress(getContext())).getBytes());
- }
与之类似的,我们还重写了 setCookie 方法以添加包含 IP 地址的附加编码信息:
- @Override
- protected void setCookie(String[] tokens, int maxAge,
- HttpServletRequest request, HttpServletResponse response) {
- // append the IP adddress to the cookie
- String[] tokensWithIPAddress =
- Arrays.copyOf(tokens, tokens.length+1 );
- tokensWithIPAddress[tokensWithIPAddress.length-1 ] =
- getUserIPAddress(request);
- super .setCookie(tokensWithIPAddress, maxAge,
- request, response);
- }
这就得到了生成新 cookie 所有需要的信息。
最后,我们要重写 processAutoLoginCookie 方法,它用来校验用户端提供的 remember me cookie 的内容。父类已经为我们解决了大部分有意思的工作,但是,为了避免调用父类冗长的代码,我们在调用它之前先进行了一次 IP 地址的校验。
- @Override
- protected UserDetails processAutoLoginCookie(
- String[] cookieTokens,
- HttpServletRequest request, HttpServletResponse response)
- {
- try
- {
- setContext(request);
- // take off the last token
- String ipAddressToken = cookieTokens[cookieTokens.length-1 ];
- if (!getUserIPAddress(request).equals(ipAddressToken))
- {
- throw new InvalidCookieException("Cookie IP Address did not
- contain a matching IP (contained '" + ipAddressToken + "' )");
- }
- return super .processAutoLoginCookie(Arrays.copyOf(cookieTokens,
- cookieTokens.length-1 ), request, response);
- }
- finally
- {
- setContext(null );
- }
- }
我们的自定义的 RememberMeServices 编码已经完成了。现在我们要进行一些微小的配置。这个类的完整源代码(包括附加的注释)都在本章的源码中能够找到。
配置自定义的 RememberMeServices
配置自定义的 RememberMeServices 实现需要两步来完成。第一步是修改 dogstore-base.xml Spring 配置文件,以添加我们刚刚完成类的 Spring Bean 声明:
- < bean class = "com.packtpub.springsecurity.security.IPTokenBasedRememberMeServices" id = "ipTokenBasedRememberMeServicesBean" >
- < property name = "key" > < value > jbcpPetStore </ value > </ property >
- < property name = "userDetailsService" ref = "userService" />
- </ bean >
第二个要进行的修改是 Spring Security 的 XML 配置文件。修改 <remember-me> 元素来引用自定义的 Spring Bean ,如下所示:
最后为 <user-service> 声明添加一个 id 属性,如果它还没有添加的话:
重启 web 应用,你将能看到新的 IP 过滤功能已经生效了。
因为 remember me cookie 是 Base64 编码的,我们能够使用一个 Base64 解码的工具得到 cookie 的值以证实我们的新增功能是否生效。如果我们这样做的话,我们能够看到一个名为 SPRING_SECURITY_REMEMBER_ME_COOKIE 的 cookie 的内容大致如下所示:
guest:1251695034322:776f8ad44034f77d13218a5c431b7b34:127.0.0.1 |
正如我们所料,你能够看到 IP 地址确实存在于 cookie 的结尾处。在 IP 地址之前,你还能够分别看到用户名、时间戳以及 MD5 的哈希值。
【调试 remember me cookie 。在尝试调试 remember me 功能时,会有两个难点。第一个就是得到 cookie 的值本身! Spring Security 并没有提供记录我们设置的 cookie 值的日志级别。我们推荐使用基于浏览器的工具如 Mozilla Firefox 下的 Chris Pederick's Web Developer 插件( http://chrispederick.com/work/web-developer/ )。基于浏览器的开发工具一般允许查看(甚至编辑) cookie 的值。第二个困难(相对来说较小)就是解码 cookie 的值。你能使用在线或离线的 Base64 解码工具来对 cookie 的值进行解码(需要记住的是添加一个等号符( = )结尾,以使其成为一个合法的 Base64 编码值)。】
如果用户是在一个共享的或负载均衡的网络设施下,如 multi-WAN 公司环境,基于 IP 的 remember me tokens 可能会出现问题。但是在大多数场景下,添加 IP 地址到 remember me 功能能够为用户提供功能更强、更好的安全层。
自定义 Remember me 的签名
好奇的读者可能会关心 remember me form 的 checkbox 名( _spring_security_remember_me )以及 cookie 的名( SPRING_SECURITY_REMEMBER_ME_COOKIE ),是否能够修改。 <remember-me> 声明是不支持这种扩展性的,但是现在我们作为一个 Spring Bean 声明了自己的 RememberMeServices 实现,那我们能够定义更多的属性来改变 checkbox 和 cookie 的名字:
- < bean class ="com.packtpub.springsecurity.web.custom.
- IPTokenBasedRememberMeServices" id = "ipTokenBasedRememberMeServicesBean" >
- < property name = "key" > < value > jbcpPetStore </ value > </ property >
- < property name = "userDetailsService" ref = "userService" />
- < property name = "parameter" value = "_remember_me" />
- < property name = "cookieName" value = "REMEMBER_ME" />
- </ bean >
不要忘记的是,还需要修改 login.jsp 页面中的 checkbox form 域以与我们声明的 parameter 值相匹配。我们建议你进行一下实验以确保理解这些设置之间的关联。
(如果想更好的理解本章节内容,建议阅读一下 Spring Security 的源码——译者注)
发表评论
-
spring-security3 配置和使用(二)承上
2011-12-22 06:42 9722、xml配置,配置内容如下: Xml代码 ... -
spring-security3 配置和使用 (一)(转载)
2011-12-22 06:43 869最近项目中要使用到spring-security,可能研究 ... -
SpringSecurity3.X--一个简单实现(转载)
2011-12-22 06:43 2623作者对springsecurity研究不深,算是个初学者吧,最 ... -
SpringSecurity3.X--验证码(转载)
2011-12-22 06:44 1014一般来说,登录时都会要求用户输入验证码,以防止恶意登录。 可 ... -
SpringSecurity3.X--前台与后台登录认证(转载)
2011-12-23 06:33 3386不过一般我们在管理系统时都会分前台与后台,也就是说,前台与后台 ... -
SpringSecurity3.X--remember-me(转载)
2011-12-22 06:44 1700笔者在SpringSecurity中配置remember-me ... -
《Spring Security3》第六章第七部分翻译(认证事件处理与小结)
2011-12-23 06:34 1268认证事件处理 ... -
《Spring Security3》第六章第六部分翻译(Spring Security基于bean的高级配置)
2011-12-23 06:34 1023Spring Security 基于bean 的高级配 ... -
《Spring Security3》第六章第五部分翻译(手动配置Spring Security设施的bean)(转载)
2011-12-23 06:34 972手动配置Spring Security 设施的be ... -
《Spring Security3》第六章第四部分翻译(异常处理)(转载)
2011-12-23 06:34 1169理解和配置异常处理 ... -
《Spring Security3》第六章第三部分翻译(Session的管理和并发)(转载)
2011-12-24 10:20 4197Session 的管理和并发 ... -
《Spring Security3》第六章第二部分翻译(自定义AuthenticationProvider)(转载)
2011-12-24 10:21 1438实现自定义的 AuthenticationProvide ... -
《Spring Security3》第六章第一部分翻译(自定义安全过滤器)(转载)
2011-12-24 10:21 1057第六章 高级配置和扩展 到目前为止,我 ... -
《Spring Security3》第五章第四部分翻译(方法安全的高级知识和小结)(转载)
2011-12-24 10:22 995方法安全的高级知 ... -
《Spring Security3》第五章第三部分翻译(保护业务层)
2011-12-24 10:22 852保护业务层 到目前为止,在 ... -
《Spring Security3》第五章第二部分翻译下(实现授权精确控制的方法——页面级权限)(转载)
2011-12-25 00:47 997使用控制器逻辑进行有条件渲染内容 ... -
《Spring Security3》第五章第二部分翻译上(实现授权精确控制的方法——页面级权限)(转载)
2011-12-25 00:47 901实现授权精确控制的方法 精确的授权指的是基于用 ... -
《Spring Security3》第五章第一部分翻译(重新思考应用功能和安全) (转载)
2011-12-25 00:47 927第五章 精确的 ... -
《Spring Security3》第四章第四部分翻译(Remember me后台存储和SSL)(转载)
2011-12-25 00:47 1217将 Remember me 功能 ... -
《Spring Security3》第四章第三部分翻译下(密码加salt)(转载)
2011-12-25 00:48 1745你是否愿意在密码上添加点salt ? 如果安 ...
相关推荐
NULL 博文链接:https://lengyun3566.iteye.com/blog/1141347
spring security3 中文版本
Spring Security 3.pdf Spring Security 3.pdf Spring Security 3.pdf Spring Security 3.pdf
该资源是基本Spring Security实战七篇文档中组织的源码,详情...ssecurity-rememberMe项目是Spring Security实战(七)的源码; 本人开发工具是IDEA,每个项目中的代码均可以运行并测试。Eclipse也是一样可以运行的。
第三章:增强用户体验 第四章:凭证安全存储 第五章:精确的访问控制 第六章:高级配置和扩展 第七章:访问控制列表(ACL) 第八章:对OpenID开放 第九章:LDAP目录服务 第十章:使用中心认证服务 第十一章:客户端...
Spring Security3 拦截 过滤器 安全,框架原理入门
3、Spring Security 2.x Overview 4、Dive Into Spring Security Authentication Authorization 5、Development Experiences & Demo 6、Q & A 张明星 5年以上保险、电信大中型项目开发经验,对JavaEE有较深入理解...
spring security spring security 中文文档
简单的 springSecurity3例子代码
Spring Security三份资料,实战Spring Security 3.x.pdf;Spring Security 3.pdf;Spring Security使用手册.pdf
Spring Security:spring家族一员。是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转...
Spring Security3 Demo ,根据Spring Security 安全权限管理手册 整理出的例子。 通过eclipse部署。
struts2 + spring3 + hibernate3 + spring security3 + mysql + tomcat sys_users;sys_roles;sys_authorities;sys_resources;sys_users_roles;sys_roles_authorities;sys_authorities_resources; PS:此项目运行不...
应用中涉及到安全认证,目前项目有独立的统一认证网关,所以登录时只需要将安全认证网关的认证后信息塞到spring security中,由security3来管理用户的权限设置。目前项目由spring security2升级到spring security3。...
spring security3 安全框架
Spring Security3
Spring Security 安全管理
springsecurity3x快速构建企业级安全 Spring Security-3.0.1中文官方文档
Spring Security in Action
Spring Security 3 By Peter Mularien和翻译 Publisher: Packt Publishing 2010 | 420 Pages | ISBN: 1847199747 | PDF | 5 MB