`
lengyun3566
  • 浏览: 456499 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
D59180b9-02f1-3380-840c-ea34da46143c
《Spring Secur...
浏览量:386248
社区版块
存档分类
最新评论

《Spring Security3》第三章第三部分翻译下(Remember me安全吗?)

阅读更多

 

Remember me是否安全?

对我们精心保护的站点来说,为了用户体验而添加的任何与安全相关的功能,都有增加安全风险的潜在可能。按照其默认方式,Remember me功能存在用户的cookie被拦截并被恶意用户重用的风险。下图展现了这种情况是如何发生的:

 


 

使用SSL(第四章进行讨论)以及其他的网络安全技术能缓解这种类型攻击的风险,但是要注意的是还有其他技术如跨站脚本攻击(XSS)能够窃取或损害一个remembered user session。为了照顾用户的易用性,我们不会愿意让用户的财产信息或个人信息因为remembered session的不合理使用而遭到篡改或窃取。

 

【尽管我们不会涉及恶意用户行为的细节,但是当你实现安全系统时,了解恶意用户所使用的攻击技术是很重要的。XSS是其中的一种技术,当然还有其他的很多种。强烈建议你了解OWASP Top Tenhttp://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设置没有变化。但我们添加了一条规则,要求用户具有GrantedAuthorityROLE_USER角色同时还要求用户被完全的认证,即这个认证的session确实是通过提供用户名、密码或等同的凭证来进行认证的。注意这里的SpEL逻辑操作语法——在SpEL中,使用andor以及not作为逻辑操作符。这是SpEL的设计者充分考虑的结果,因为&&操作符在XML中很难被使用。

 

如果你在应用中尝试运行,如果以remember me功能登录并试图访问“My Account”链接,你将会得到一个403访问拒绝的提示,这说明这个地址已经被适当地保护了。出现错误界面是因为我们应用的配置还是使用默认的AccessDeniedHandler,这个类负责捕获和响应AccessDeniedException的信息。我们将会在第六章学习AccessDeniedException怎样被处理时,自定义这个行为。

 

【不使用表达式来实现完全认证的检查。如果你的应用不使用SpEL表达式来进行访问控制声明,你可以通过使用IS_AUTHENTICATED_FULLY访问规则来检查用户是不是进行了完整的认证(如:access=" IS_AUTHENTICATED_FULLY")。但要注意的是,这种标准的角色设置声明并没有SpEL那样强的表现力,所以如果要处理复杂的boolean表达式的时候,可能会比较困难。】

 

错误处理尚没有添加,但是你可以看到通过这种方式将remember me的易用性与更高层次的安全性结合了起来,用户访问敏感的信息时就会被要求提供完整的凭证信息。

构建一个关联IPRemember 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包下创建这个类:

 

public class IPTokenBasedRememberMeServices extends
    TokenBasedRememberMeServices {

 

 还有一些简单的方法来设置和获取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 SecurityXML配置文件。修改<remember-me>元素来引用自定义的Spring Bean,如下所示:

 

<remember-me key="jbcpPetStore" 
   services-ref="ipTokenBasedRememberMeServicesBean"/>

 最后为<user-service>声明添加一个id属性,如果它还没有添加的话:

 

<user-service  id="userService">

 重启web应用,你将能看到新的IP过滤功能已经生效了。

 

因为remember me cookieBase64编码的,我们能够使用一个Base64解码的工具得到cookie的值以证实我们的新增功能是否生效。如果我们这样做的话,我们能够看到一个名为SPRING_SECURITY_REMEMBER_ME_COOKIEcookie的内容大致如下所示:

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公司环境,基于IPremember me tokens可能会出现问题。但是在大多数场景下,添加IP地址到remember me功能能够为用户提供功能更强、更好的安全层。

 

 

自定义Remember me的签名

好奇的读者可能会关心remember me formcheckbox名(_spring_security_remember_me)以及cookie的名(SPRING_SECURITY_REMEMBER_ME_COOKIE),是否能够修改。<remember-me>声明是不支持这种扩展性的,但是现在我们作为一个Spring Bean声明了自己的RememberMeServices实现,那我们能够定义更多的属性来改变checkboxcookie的名字:

 

 

<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的源码——译者注)

 

  • 大小: 28.3 KB
分享到:
评论
4 楼 9光光9 2014-09-28  
三年前的文章,今天测了下,取出ip值的
3 楼 asdcer 2013-01-10  
在3.1.3版本中不成功,cookieTokens[cookieTokens.length-1]不是ip,而是makeTokenSignature后的值,而这个值是MD5加密后的值,无法取出值中的ip地址
2 楼 tywo45 2012-07-03  
适用,刚才我有个setCookie方法没有copy进去。
1 楼 tywo45 2012-07-03  
这个适用于spring security3.1.0吗?好像不适用。

相关推荐

    少儿编程scratch项目源代码文件案例素材-绝地求生.zip

    少儿编程scratch项目源代码文件案例素材-绝地求生.zip

    嵌入式八股文面试题库资料知识宝典-文思创新面试题2010-04-08.zip

    嵌入式八股文面试题库资料知识宝典-文思创新面试题2010-04-08.zip

    一种基于剪切波和特征信息检测的太阳斑点图融合算法.pdf

    一种基于剪切波和特征信息检测的太阳斑点图融合算法.pdf

    并联型APF有源电力滤波器Matlab Simulink仿真:dq与αβ坐标系下的谐波无功检测与PI控制及SVPWM调制

    内容概要:本文详细介绍了并联型有源电力滤波器(APF)在Matlab/Simulink环境下的仿真研究。主要内容涵盖三个关键技术点:一是dq与αβ坐标系下的谐波和无功检测,利用dq变换和FBD技术实现实时检测;二是两相旋转坐标系(dq)与两相静止坐标系(αβ)下的PI控制,通过调整比例和积分环节实现精准控制;三是SVPWM调制方式的应用,通过优化开关时序提升系统效率和性能。文中还提供了详细的仿真介绍文档,包括模型搭建、参数设定以及结果分析。 适合人群:从事电力电子、自动化控制领域的研究人员和技术人员,尤其是对电力滤波器仿真感兴趣的读者。 使用场景及目标:适用于需要深入了解并联型APF工作原理和实现方式的研究人员,旨在通过仿真工具掌握谐波和无功检测、PI控制及SVPWM调制的具体应用。 其他说明:本文不仅提供了理论知识,还结合了实际操作步骤,使读者能够通过仿真模型加深对APF的理解。

    Arduino KEY实验例程【正点原子ESP32S3】

    Arduino KEY实验例程,开发板:正点原子EPS32S3,本人主页有详细实验说明可供参考。

    嵌入式八股文面试题库资料知识宝典-嵌入式C语言面试题汇总(66页带答案).zip

    嵌入式八股文面试题库资料知识宝典-嵌入式C语言面试题汇总(66页带答案).zip

    .archivetempdebug.zip

    .archivetempdebug.zip

    嵌入式系统开发_CH551单片机_USB_HID复合设备模拟_基于CH551单片机的USB键盘鼠标复合设备模拟器项目_用于通过CH551微控制器模拟USB键盘和鼠标输入设备_实现硬.zip

    嵌入式系统开发_CH551单片机_USB_HID复合设备模拟_基于CH551单片机的USB键盘鼠标复合设备模拟器项目_用于通过CH551微控制器模拟USB键盘和鼠标输入设备_实现硬

    少儿编程scratch项目源代码文件案例素材-剑客冲刺.zip

    少儿编程scratch项目源代码文件案例素材-剑客冲刺.zip

    少儿编程scratch项目源代码文件案例素材-火影.zip

    少儿编程scratch项目源代码文件案例素材-火影.zip

    两极式单相光伏并网系统的Boost电路与桥式逆变仿真及优化方法

    内容概要:本文详细介绍了两极式单相光伏并网系统的组成及其仿真优化方法。前级采用Boost电路结合扰动观察法(P&O)进行最大功率点跟踪(MPPT),将光伏板输出电压提升至并网所需水平;后级利用全桥逆变加L型滤波以及电压外环电流内环控制,确保并网电流与电网电压同频同相,实现高效稳定的并网传输。文中还提供了具体的仿真技巧,如开关频率设置、L滤波参数计算和并网瞬间软启动等,最终实现了98.2%的系统效率和低于0.39%的总谐波失真率(THD)。 适合人群:从事光伏并网系统研究、设计和开发的技术人员,特别是对Boost电路、MPPT算法、逆变技术和双环控制系统感兴趣的工程师。 使用场景及目标:适用于希望深入了解两极式单相光伏并网系统的工作原理和技术细节的研究人员和工程师。目标是在实际项目中应用这些理论和技术,提高光伏并网系统的效率和稳定性。 其他说明:文中提供的仿真技巧和伪代码有助于读者更好地理解和实现相关算法,在实践中不断优化系统性能。同时,注意电网电压跌落时快速切换到孤岛模式的需求,确保系统的安全性和可靠性。

    昭通乡镇边界,矢量边界,shp格式

    矢量边界,行政区域边界,精确到乡镇街道,可直接导入arcgis使用

    嵌入式八股文面试题库资料知识宝典-嵌入式c面试.zip

    嵌入式八股文面试题库资料知识宝典-嵌入式c面试.zip

    嵌入式八股文面试题库资料知识宝典-I2C总线.zip

    嵌入式八股文面试题库资料知识宝典-I2C总线.zip

    岩土工程中随机裂隙网络注浆模型及其应用:不同压力下注浆效果的研究

    内容概要:本文详细介绍了三种注浆模型——随机裂隙网络注浆模型、基于两相达西定律的注浆模型、基于层流和水平集的注浆扩散模型。首先,随机裂隙网络注浆模型基于地质学原理,模拟裂隙网络发育的实际地质情况,在不同注浆压力下进行注浆作业,以增强地基稳定性和提高承载能力。其次,基于两相达西定律的注浆模型利用数学公式模拟裂隙网络中的流体输送过程,适用于裂隙网络地质条件下的注浆效果分析。最后,基于层流和水平集的注浆扩散模型通过引入层流特性和水平集方法,更准确地模拟注浆过程中的扩散过程。文中还讨论了不同注浆压力对注浆效果的影响,并提出了优化建议。 适合人群:从事岩土工程、地基加固等相关领域的工程师和技术人员。 使用场景及目标:①帮助工程师选择合适的注浆模型和注浆压力;②为实际工程项目提供理论支持和技术指导;③提升地基加固的效果和效率。 其他说明:文章强调了在实际应用中需要结合地质条件、裂隙网络特点等因素进行综合分析,以达到最佳注浆效果。同时,鼓励不断创新注浆工艺和方法,以满足日益增长的地基加固需求。

    COMSOL Multiphysics 5.5与6.0版本Ar棒板粗通道流注放电仿真的电子特性分析

    内容概要:本文详细比较了COMSOL Multiphysics软件5.5和6.0版本在模拟Ar棒板粗通道流注放电现象方面的异同。重点探讨了不同版本在处理电子密度、电子温度、电场强度以及三维视图等方面的优缺点。文中不仅介绍了各版本特有的操作方式和技术特点,还提供了具体的代码实例来展示如何进行精确的仿真设置。此外,文章还讨论了网格划分、三维数据提取和电场强度后处理等方面的技术难点及其解决方案。 适合人群:从事等离子体物理研究的专业人士,尤其是熟悉COMSOL Multiphysics软件并希望深入了解其最新特性的研究人员。 使用场景及目标:帮助用户选择合适的COMSOL版本进行高效、精确的等离子体仿真研究,特别是在处理复杂的Ar棒板粗通道流注放电现象时提供指导。 其他说明:文章强调了在实际应用中,选择COMSOL版本不仅要考虑便捷性和视觉效果,还需兼顾仿真精度和可控性。

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_8.doc.zip

    嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_8.doc.zip

    通信系统中波形优化与捷变频、PRT抗干扰技术及ISRJ联合优化的应用研究

    内容概要:本文详细介绍了在现代通信系统中,抗干扰技术的重要性和具体应用方法。首先阐述了抗干扰技术的背景及其重要性,随后分别讨论了捷变频技术和波形优化技术的具体机制和优势。捷变频技术能快速改变工作频率,防止被干扰源锁定;波形优化技术则通过改进信号波形来提升抗干扰性能。接着,文章探讨了两种技术相结合的协同效应,最后重点介绍了发射信号及接收滤波器联合优化的抗干扰策略(ISRJ),这是一种综合性优化手段,旨在最大化抗干扰效果并提高通信质量。 适合人群:从事通信工程及相关领域的研究人员和技术人员,尤其是关注抗干扰技术的专业人士。 使用场景及目标:适用于需要提升通信系统稳定性和可靠性的场合,如军事通信、卫星通信等领域。目标是帮助技术人员理解和掌握先进的抗干扰技术,应用于实际项目中。 其他说明:文中提到的技术不仅限于理论层面,还涉及具体的实施细节和应用场景,有助于读者深入理解并应用于实践中。

    少儿编程scratch项目源代码文件案例素材-吉他英雄.zip

    少儿编程scratch项目源代码文件案例素材-吉他英雄.zip

    独立光伏系统仿真模型研究:Boost升压与双闭环控制策略及技术应用分析

    内容概要:本文详细探讨了独立光伏系统的仿真模型及其控制策略。首先介绍了光伏组串模型的搭建方法,利用Simulink中的S函数实现特性曲线,确保高精度输出。接着重点讨论了Boost升压电路的改进型功率环控制策略,通过非线性积分器有效避免了占空比过高的风险,使系统震荡幅度显著降低。对于储能部分,采用双向DCDC转换器,实现了充放电模式间的平滑切换,并通过互补PWM技术增强了硬件死区保护效果。逆变器部分则采用了单极调制方式,减少了开关损耗,并优化了LC滤波参数的设计,确保了低谐波失真率。此外,还设计了一个基于继电器的智能负载模拟系统,能够根据交流电压的变化自动调节负载,提高了仿真的效率和准确性。最后,通过对整个系统的动态优先级管理,使得光伏出力波动时储能系统可以迅速响应,保持直流母线电压稳定。 适合人群:从事光伏系统设计、仿真建模以及电力电子领域的工程师和技术人员。 使用场景及目标:适用于需要深入了解独立光伏系统内部工作原理的研究人员,帮助他们掌握从光伏组串到逆变器各环节的具体实现细节,为实际工程项目提供可靠的理论支持和技术指导。 其他说明:文中提供了大量MATLAB/Simulink代码片段和具体参数设置建议,便于读者理解和复现实验结果。同时强调了不同控制策略之间的对比分析,指出了最优解的选择依据。

Global site tag (gtag.js) - Google Analytics