- 浏览: 306065 次
文章分类
最新评论
-
流年末年:
那四个参数还是没看懂.....能不能解释下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 10642、xml配置,配置内容如下: Xml代码 ... -
spring-security3 配置和使用 (一)(转载)
2011-12-22 06:43 958最近项目中要使用到spring-security,可能研究 ... -
SpringSecurity3.X--一个简单实现(转载)
2011-12-22 06:43 2676作者对springsecurity研究不深,算是个初学者吧,最 ... -
SpringSecurity3.X--验证码(转载)
2011-12-22 06:44 1069一般来说,登录时都会要求用户输入验证码,以防止恶意登录。 可 ... -
SpringSecurity3.X--前台与后台登录认证(转载)
2011-12-23 06:33 3461不过一般我们在管理系统时都会分前台与后台,也就是说,前台与后台 ... -
SpringSecurity3.X--remember-me(转载)
2011-12-22 06:44 1749笔者在SpringSecurity中配置remember-me ... -
《Spring Security3》第六章第七部分翻译(认证事件处理与小结)
2011-12-23 06:34 1346认证事件处理 ... -
《Spring Security3》第六章第六部分翻译(Spring Security基于bean的高级配置)
2011-12-23 06:34 1057Spring Security 基于bean 的高级配 ... -
《Spring Security3》第六章第五部分翻译(手动配置Spring Security设施的bean)(转载)
2011-12-23 06:34 1032手动配置Spring Security 设施的be ... -
《Spring Security3》第六章第四部分翻译(异常处理)(转载)
2011-12-23 06:34 1248理解和配置异常处理 ... -
《Spring Security3》第六章第三部分翻译(Session的管理和并发)(转载)
2011-12-24 10:20 4232Session 的管理和并发 ... -
《Spring Security3》第六章第二部分翻译(自定义AuthenticationProvider)(转载)
2011-12-24 10:21 1525实现自定义的 AuthenticationProvide ... -
《Spring Security3》第六章第一部分翻译(自定义安全过滤器)(转载)
2011-12-24 10:21 1128第六章 高级配置和扩展 到目前为止,我 ... -
《Spring Security3》第五章第四部分翻译(方法安全的高级知识和小结)(转载)
2011-12-24 10:22 1061方法安全的高级知 ... -
《Spring Security3》第五章第三部分翻译(保护业务层)
2011-12-24 10:22 894保护业务层 到目前为止,在 ... -
《Spring Security3》第五章第二部分翻译下(实现授权精确控制的方法——页面级权限)(转载)
2011-12-25 00:47 1030使用控制器逻辑进行有条件渲染内容 ... -
《Spring Security3》第五章第二部分翻译上(实现授权精确控制的方法——页面级权限)(转载)
2011-12-25 00:47 977实现授权精确控制的方法 精确的授权指的是基于用 ... -
《Spring Security3》第五章第一部分翻译(重新思考应用功能和安全) (转载)
2011-12-25 00:47 952第五章 精确的 ... -
《Spring Security3》第四章第四部分翻译(Remember me后台存储和SSL)(转载)
2011-12-25 00:47 1270将 Remember me 功能 ... -
《Spring Security3》第四章第三部分翻译下(密码加salt)(转载)
2011-12-25 00:48 1815你是否愿意在密码上添加点salt ? 如果安 ...
相关推荐
《Spring Security3》第四章第四部分主要探讨了Remember me服务的后台存储机制以及如何结合SSL(Secure Sockets Layer)来增强应用的安全性。这一部分的知识点涵盖了Spring Security中Remember me的功能,用户身份...
文档的翻译者lengyun3566在博客中提到,他翻译了Spring Security3的文档,并在每篇文章的开头强调了版权信息,要求转载时必须注明出处。这表明了作者对知识产权的尊重以及对读者的责任感。 ### 第一章:Spring ...
自此之后,Spring Security 成为了 Spring 生态系统中的一个重要组成部分,不断迭代更新,以适应不断变化的安全需求和技术发展。 ##### 1.3 发行版本号 Spring Security 3.0.1 是在 Spring Security 3.0 的基础上...
- 默认情况下,Spring Security 开启了跨站请求伪造(CSRF)防护,通过生成并验证CSRF令牌,防止恶意第三方发起未经授权的操作。 6. **表达式式语言**: - Spring Security 使用一种强大的表达式语言(EL),如`...
- Spring Security 3引入了CSRF(跨站请求伪造)防护,通过添加一个不可预测的令牌到表单提交中,防止恶意第三方发起未经授权的操作。 5. **国际化支持**: - 支持多语言界面,可以根据用户的首选语言显示错误...
7. **OAuth2 and JWT支持**:Spring Security 提供了对OAuth2和JSON Web Tokens (JWT) 的支持,这在现代微服务架构中非常重要,因为它允许第三方应用安全地与你的服务进行交互。 8. **表达式语言(SpEL)**:Spring...
- Spring Security 3.x也可以与OAuth2协议集成,支持第三方服务的授权,提供安全的API访问。 8. **自定义扩展** - Spring Security的灵活性允许开发者根据需求自定义认证和授权策略,可以通过实现接口或继承类来...
#### 第三章:增强用户体验 **自定义登录页面** - 通过自定义登录页面提高用户体验,可以更好地融入网站的设计风格。 **实现Remember-Me功能** - **原理**:记住用户的登录状态,下次访问时自动登录。 - **实现**...
- OAuth 2.0 是一个开放标准,用于授权第三方应用访问用户资源。Spring Security 支持 OAuth 2.0,可以帮助开发者构建安全的授权服务器和资源服务器。 通过这个教程,你将了解 Spring Security 的核心概念,并能...
7. **OAuth2支持**:SpringSecurity还支持OAuth2协议,提供了一种安全的第三方应用访问资源的方式。 8. **Remember-Me服务**:允许用户在一段时间内无须再次输入登录凭据,提高用户体验。 9. **自定义扩展**:...
Spring Security 是一个强大的和高度可定制的身份验证和...总的来说,Spring Security 3.x第五章的实例将帮助开发者深入理解这个框架的使用,通过具体的代码示例来实践安全性配置,从而更好地保护他们的Spring应用。
- Spring Security也支持OAuth2协议,允许第三方应用获取资源服务器上的数据,同时提供了客户端和资源服务器的实现。 8. **异常处理**: - 当认证或授权失败时,Spring Security会抛出相应的异常,如...
《Spring Security 安全权限管理手册》是一本深入解析Spring Security框架的专业指南,对于正在学习或已经在使用Spring框架的开发者来说,它提供了丰富的知识和实践经验。Spring Security是Spring生态系统中的一个...
#### 第三章:增强用户体验 - **自定义登录页**: - **实现自定义的登录页**:提供具体实现步骤。 - **理解退出功能**: - **在站点页头上添加“LogOut”链接**:说明如何在网站中添加退出链接。 - **退出是怎么...
标题:springsecurity3.1.pdf 描述:springsecurity3.1.pdf 标签:spring security3.1 部分内容:SpringSecurity Reference Documentation by Ben Alex and Luke Taylor 3.1.4.RELEASE **一、Spring Security 3.1...
根据给定的信息,我们可以从《Spring Security3 中文版》一书中提炼出多个重要的知识点,主要涉及Spring Security的基础概念、具体实现以及高级配置等方面。下面将详细解释每一部分的关键内容。 ### 第一章:一个不...
Spring Security支持OAuth2协议,允许第三方应用通过授权获取用户资源。这对于构建API或微服务环境中的身份验证和授权非常有用。 9. **配置**: Spring Security的配置可以通过XML、Java配置或者使用`@...
SpringSecurity是Java领域中一款强大的安全框架,专为Web应用程序设计,用于实现身份验证和授权。这个名为"SpringSecurity素材.zip"的压缩包文件很可能包含了关于如何使用SpringSecurity进行安全控制的各种资料。...
3. **CSRF(跨站请求伪造)防护**:防止恶意第三方模拟用户发送请求。 4. **会话管理**:包括会话固定保护、会话超时检测等功能,增强了系统的安全性。 5. **Remember Me服务**:允许用户在一段时间内免登录访问系统...