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

《Spring Security3》第三章第四部分翻译(修改密码)

阅读更多

 

实现修改密码管理

现在我们将要对基于内存的UserDetailsService进行简单的扩展以使其支持用户修改密码。因为这个功能对用户名和密码存于数据库的场景更有用,所以基于o.s.s.core.userdetails.memory.InMemoryDaoImpl扩展的实现不会关注存储机制,而是关注框架对这种方式扩展的整体流程和设计。在第四章中,我们将通过将其转移到数据库后台存储来进一步扩展我们的基本功能。

扩展基于内存的凭证存储以支持修改密码

Spring Security框架提供的InMemoryDaoImpl内存凭证存储使用了一个简单的map来存储用户名以及关联的UserDetailsInMemoryDaoImpl使用的UserDetails实现类是o.s.s.core.userdetails.User,这个实现类将会在Spring Security API中还会看到。

 

这个扩展的设计有意的进行了简化并省略了一些重要的细节,如需要用户在修改密码前提供他们的旧密码。添加这些功能将作为练习留给读者。

InMemoryChangePasswordDaoImpl扩展InMemoryDaoImpl

我们要首先写自定义的类来扩展基本的InMemoryDaoImpl,并提供允许用户修改密码的方法。因为用户是不可改变的对象,所以我们copy已经存在的User对象,只是将密码替换为用户提交的值。在这里我们定义一个接口在后面的章节中将会重用,这个接口提供了修改密码功能的一个方法:

 

package com.packtpub.springsecurity.security;
// imports omitted
public interface IChangePassword extends UserDetailsService {  
void changePassword(String username, String password);
}

 以下的代码为基于内存的用户数据存储提供了修改密码功能:

 

package com.packtpub.springsecurity.security;
public class InMemoryChangePasswordDaoImpl extends InMemoryDaoImpl 
implements IChangePassword {
  @Override
  public void changePassword(String username, 
                String password) {
    // get the UserDetails
    User userDetails = 
        (User) getUserMap().getUser(username);
    // create a new UserDetails with the new password
    User newUserDetails = 
        new User(userDetails.getUsername(),password,
        userDetails.isEnabled(), 
        userDetails.isAccountNonExpired(),
      userDetails.isCredentialsNonExpired(),
        userDetails.isAccountNonLocked(),
        userDetails.getAuthorities());
    // add to the map
    getUserMap().addUser(newUserDetails);
  }
}

 比较幸运的是,只有一点代码就能将这个简单的功能加到自定义的子类中了。我们接下来看看添加自定义UserDetailsServicepet store应用中会需要什么样的配置。

配置Spring Security来使用InMemoryChangePasswordDaoImpl

现在,我们需要重新配置Spring SecurityXML配置文件以使用新的UserDetailsService实现。这可能比我们预想的要困难一些,因为<user-service>元素在Spring Security的处理过程中有特殊的处理。需要明确声明我们的自定义bean并移除我们先前声明的<user-service>元素。我们需要把:

 

<authentication-manager alias="authenticationManager">
  <authentication-provider>
    <user-service id="userService">
      <user authorities="ROLE_USER" name="guest" password="guest"/>
    </user-service>
  </authentication-provider>
</authentication-manager>

 修改为:

 

<authentication-provider user-service-ref="userService"/>

 在这里我们看到的user-service-ref属性,引用的是一个iduserServiceSpring Bean。所以在dogstore-base.xml Spring Beans配置文件中,声明了如下的bean

 

<bean id="userService" class="com.packtpub.springsecurity.security.
InMemoryChangePasswordDaoImpl">
  <property name="userProperties">
    <props>
      <prop key="guest">guest,ROLE_USER</prop>
    </props>
  </property>
</bean>

 你可能会发现,这里声明用户的语法不如<user-service>包含的<user>元素更易读。遗憾的是,<user>元素只能使用在默认的InMemoryDaoImpl实现类中,我们不能在自定义的UserDetailsService中使用了。在这里例子中,这个限制使得事情稍微复杂了一点,但是在实际中,没有人会愿意长期的将用户定义信息放在配置文件中。对于感兴趣的读者,Spring Security 3参考文档中的6.2节详细描述了以逗号分隔的提供用户信息的语法。

【高效使用基于内存的UserDetailsService。有一个常见的场景使用基于内存的UserDetailsService和硬编码的用户列表,那就是编写安全组件的单元测试。编写单元测试的人员经常编码或配置最简单的场景来测试组件的功能。使用基于内存的UserDetailsService以及定义良好的用户和GrantedAuthority值为测试编写人员提供了很可控的测试环境。】

 

到现在,你可以重启JBCP Pets应用,应该没有任何的配置错误报告。我们将在这个练习的最后的两步中,完成UI的功能。

构建一个修改密码的页面

我们接下来将会建立一个允许用户修改密码的简单页面。



 这个页面将会通过一个简单的链接添加到“My Account”页面。首先,我们在/account/home.jsp文件中添加一个链接:

 

<p>
  Please find account functions below...
</p>
<ul>
  <li><a href="changePassword.do">Change Password</a></li>
</ul>

 接下来,在/account/ changePassword.jsp文件中建立“Change Password”页面本身:

 

<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<jsp:include page="../common/header.jsp">
  <jsp:param name="pageTitle" value="Change Password"/>
</jsp:include>
<h1>Change Password</h1>
<form method="post">
  <label for="password">New Password</label>:
  <input id="password" name="password" size="20" maxlength="50" 
type="password"/>
  <br />
  <input type="submit" value="Change Password"/> 
</form>
<jsp:include page="../common/footer.jsp"/>
 

 

最后我们还要添加基于Spring MVCAccountController来处理密码修改的请求(在前面的章节中我们没有介绍AccountController,它是账号信息主页的简单处理类)。

AccountController添加修改密码的处理

我们需要将对自定义UserDetailsService的应用注入到com.packtpub.springsecurity.web.controller.AccountController,这样我们就能使用修改密码的功能了。Spring@Autowired注解实现了这一功能:

 

@Autowired
private IChangePassword changePasswordDao;

 两个接受请求的方法分别对应渲染form以及处理POST提交的form数据:

 

@RequestMapping(value="/account/changePassword.
do",method=RequestMethod.GET)
public void showChangePasswordPage() {  
}
@RequestMapping(value="/account/changePassword.
do",method=RequestMethod.POST)
public String submitChangePasswordPage(@RequestParam("password") 
String newPassword) {
  Object principal = SecurityContextHolder.getContext().
getAuthentication().getPrincipal();
  String username = principal.toString();
  if (principal instanceof UserDetails) {
username = ((UserDetails)principal).getUsername();
}
  changePasswordDao.changePassword(username, newPassword);
  SecurityContextHolder.clearContext();
  return "redirect:home.do";
}

 完成这些配置后,重启应用,并在站点的“My Account”下找到“Change Password”功能。

练习笔记

比较精细的读者可能意识到这个修改密码的form相对于现实世界的应用来说太简单了。确实,很多的修改密码实现要复杂的多,并可能包含如下的功能:

l  密码确认——通过两个文本框,确保用户输入的密码是正确的;

l  旧密码确认——通过要求用户提供要修改的旧密码,增加安全性(这对使用remember me功能的场景特别重要);

l  密码规则校验——检查密码的复杂性以及密码是否安全。

 

你可能也会注意到当你使用这个功能的时,会被自动退出。这是因为SecurityContextHolder.clearContext()调用导致的,它会移除用户的SecurityContext并要求他们重新认证。在练习中,我们需要给用户做出提示或者找到方法让用户免于再次认证。

小结

在本章中,我们更细节的了解了认证用户的生命周期并对JBCP Pet  Store进行了结构性的修改。我们通过添加真正的登录和退出功能,进一步的满足了安全审计的要求,并提升了用户的体验。我们也学到了如下的技术:

l  配置并使用基于Spring MVC的自定义用户登录界面;

l  配置Spring Security的退出功能;

l  使用remember me功能;

l  通过记录IP地址,实现自定义的remember me功能;

l  实现修改密码功能;

l  自定义UserDetailsServiceInMemoryDaoImpl

在第四章中,我们将会使用基于数据库的认证信息存储并学习怎样保证数据库中的密码和其他敏感数据的安全。

  • 大小: 21.9 KB
5
2
分享到:
评论
2 楼 zhonghuafy 2011-07-19  
感谢楼主的翻译!非常好。不知楼主有没有英文版的电子书,可否发给我一份?Zhonghuafy@gmail.com。

等楼主翻译完,可以联系原作者商议出版。或者做成pdf格式的电子文档。any way,谢谢你的工作!
1 楼 xosadan 2011-07-09  
谢谢分享。。

相关推荐

    《Spring Security3》第四章第四部分翻译(Remember me后台存储和SSL)附前四章doc文件

    《Spring Security3》第四章第四部分主要探讨了Remember me服务的后台存储机制以及如何结合SSL(Secure Sockets Layer)来增强应用的安全性。这一部分的知识点涵盖了Spring Security中Remember me的功能,用户身份...

    spring security3 中文版本

    自此之后,Spring Security 成为了 Spring 生态系统中的一个重要组成部分,不断迭代更新,以适应不断变化的安全需求和技术发展。 ##### 1.3 发行版本号 Spring Security 3.0.1 是在 Spring Security 3.0 的基础上...

    Spring Security in Action

    Spring Security 实践指南 Spring Security 是一个基于 Java 的安全框架,旨在提供身份验证、授权和访问控制等功能。下面是 Spring Security 的主要知识点: 一、身份验证(Authentication) 身份验证是指对用户...

    Spring Security3

    #### 第三章:增强用户体验 **自定义登录页面** - 通过自定义登录页面提高用户体验,可以更好地融入网站的设计风格。 **实现Remember-Me功能** - **原理**:记住用户的登录状态,下次访问时自动登录。 - **实现**...

    springSecurity3中文文档

    第二章:springsecurity起步 第三章:增强用户体验 第四章:凭证安全存储 第五章:精确的访问控制 第六章:高级配置和扩展 第七章:访问控制列表(ACL) 第八章:对OpenID开放 第九章:LDAP目录服务 第十章:使用...

    Spring security oauth源码

    OAuth是一种授权协议,允许用户让第三方应用在不分享其密码的情况下,访问其存储在另一服务提供者的数据。OAuth 1.0a主要处理签名机制,而OAuth 2.0则简化了流程,提供了授权码、隐式、密码和客户端凭据四种授权类型...

    基于spring security + oauth2 + jwt ,可优雅集成第三方登录.zip

    本项目以"基于spring security + oauth2 + jwt,可优雅集成第三方登录"为主题,旨在提供一个能够无缝整合第三方登录系统的解决方案。 Spring Security是一个强大的安全框架,它为Java和Java EE应用程序提供了全面的...

    spring security第一个项目

    在“spring security第一个项目”中,我们将探讨如何搭建一个基础的Spring Security环境,实现用户登录验证以及权限控制。 首先,我们需要理解Spring Security的基本架构。它由四个主要组件组成:Filter Security ...

    Spring Security 文档

    在使用Spring Security的四种方法中,第三种方法是最为推荐的,因为它提供了最大的可扩展性和灵活性。通过数据库存储,可以方便地管理和维护用户、角色和权限,而自定义过滤器和接口实现则允许我们根据业务逻辑定制...

    springsecurity3.1.pdf

    标题: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 security oauth2.0 (讲义+代码)

    OAuth2.0 是一种授权框架,允许第三方应用在用户许可的情况下访问其受保护的资源,而无需共享用户凭证。本讲义结合代码将深入探讨如何利用Spring Security OAuth2.0 实现这一目标。 首先,OAuth2.0 有四个核心角色...

    SpringSecurity+OAuth2+JWT分布式权限控制.zip

    本项目“SpringSecurity+OAuth2+JWT分布式权限控制”旨在提供一个完整的解决方案,帮助开发者构建安全的、基于微服务的分布式应用程序。 Spring Security 是一个强大的和高度可定制的身份验证和授权框架,适用于...

    spring security3中文文档

    #### 第三章:增强用户体验 - **自定义登录页**: - **实现自定义的登录页**:提供具体实现步骤。 - **理解退出功能**: - **在站点页头上添加“LogOut”链接**:说明如何在网站中添加退出链接。 - **退出是怎么...

    Spring Security笔记.rar

    2. **OAuth2集成**:Spring Security支持OAuth2协议,可以用于实现第三方登录(如Facebook、Google)。 3. **CSRF防护**:Spring Security提供跨站请求伪造(CSRF)防护机制,防止恶意攻击。 总的来说,Spring ...

    springsecurity入门实例

    3. **社交登录**:集成 OAuth2 或其他第三方登录服务,如 Google、Facebook,为用户提供便利。 在"TestSecurity"这个实例中,你将会看到一个简单的 Spring Security 配置和运行流程,包括登录、权限控制以及可能的...

    spring security从零学起

    4. OAuth2集成:Spring Security可以与OAuth2结合,实现第三方登录功能。 六、源码分析 深入理解Spring Security的源码有助于定制更复杂的解决方案。关键类如AbstractAuthenticationProcessingFilter、...

    自定义Spring Security的身份验证失败处理方法

    三、Spring Security 的 AuthenticationFailureHandler Spring Security 提供了一个默认的身份验证失败处理组件,但是,我们发现于默认行为不足以满足实际要求的情况是很常见的。如果是这种情况,我们可以创建自己...

Global site tag (gtag.js) - Google Analytics