《Spring Security3》第四章第一部分翻译下(自定义的UserDetailsService)(转载)

实现自定义的JDBC UserDetailsService

正如在前面章节中的那个练习,我们将以基本的 JdbcDaoImpl 作为起点,将其进行扩展以支持修改密码功能。

创建一个自定义的 JDBC UserDetailsService

com.packtpub.springsecurity.security 包下创建如下的类:

 

Java代码   收藏代码
  1. public   class  CustomJdbcDaoImpl  extends  JdbcDaoImpl  implements    
  2. IChangePassword {  
  3.   public   void  changePassword(String username, String password) {  
  4.     getJdbcTemplate()   
  5.     update("UPDATE USERS SET PASSWORD = ? WHERE USERNAME = ?" ,  
  6.             password, username);  
  7.   }  
  8. }  

 你可以看到这个类扩展了 JdbcDaoImpl 默认类,提供了按照用户请求更新数据库中密码的功能。我们使用标准的 Spring JDBC模板 完成这个功能。

为自定义的 JDBC UserDetailsService 添加 Spring bean 声明

dogstore-base.xml 配置文件中,添加如下的 Spring Bean 声明:

 

Xml代码   收藏代码
  1. < bean   id = "jdbcUserService"    
  2.       class = "com.packtpub.springsecurity.security.CustomJdbcDaoImpl" >   
  3.   < property   name = "dataSource"   ref = "dataSource" />   
  4. </ bean >   

 同样的, dataSource Bean 引用指向了 <embedded-database> 声明,我们使用这个声明来安装 HSQL 内存数据库。

 

扫描二维码关注公众号,回复: 753250 查看本文章

你会发现自定义的 UserDetailsService 允许我们与数据库直接交互。在接下来的例子中,我们将使用这个功能来扩展 UserDetailsService 的基本功能。在使用 Spring Security 的复杂应用中,这种类型的个性化是很常见的。

基于JDBC 的内置用户管理

正如上面简单 JdbcDaoImpl 扩展所描述的那样,开发人员可能会扩展这个类,但同时也会保留基本的功能。而我们要实现更复杂功能时,如用户注册( online store 所必须的)与用户管理功能、站点的管理员创建用户、更新密码等,又会怎样呢?

 

尽管这些功能借助 JDBC 语句都能相对容易的实现,但是 Spring Security 还是为我们提供了内置的功能以支持对数据库里的用户进行创建、读取、更新和删除的操作。这对简单的系统来说是很有用的,同时也为构建自定义需求的用户提供了很好的起点。

 

实现类 o.s.s.provisioning.JdbcUserDetailsManager 扩展了 JdbcDaoImpl 的功能,提供了一些很有用的与用户相关的方法,这些方法的一部分在 o.s.s.provisioning.UserDetailsManager 接口中进行了定义:

方法

描述

void createUser(UserDetails user)

根据给定的 UserDetails 创建一个新用户,并包含所有声明的 GrantedAuthority

void updateUser(final UserDetails user)

根据给定的 UserDetails 更新一个用户。更新其 GrantedAuthority 并将其从用户缓存中清除。

void deleteUser(String username)

根据给定的用户名删除用户,并将其从用户缓存中清除。

boolean userExists(String username)

根据给定的用户名判断用户是否存在(不管是否可用)。

void changePassword(String oldPassword, String newPassword)

修改当期登录用户的密码。为了使得操作成功,用户必须提供正确的当期密码。

 

正如你所见, JdbcUserDetailsManager changePassword 方法正好满足了我们 CustomJdbcDaoImpl 的不足——在修改之前,它会检验用户已存在密码。让我们看一下将 CustomJdbcDaoImpl 替换为 JdbcUserDetailsManager 需要怎样的配置步骤。

 

首先,我们需要在 dogstore-base.xml 中声明 JdbcUserDetailsManager bean

 

Xml代码   收藏代码
  1. < bean   id = "jdbcUserService"    
  2.       class ="org.springframework.security   
  3.              .provisioning.JdbcUserDetailsManager">   
  4.   < property   name = "dataSource"   ref = "dataSource" />   
  5.   < property   name = "authenticationManager"    
  6.             ref = "authenticationManager" />   
  7. </ bean >   

  AuthenticationManager 的引用要匹配我们之前 dogstore-security.xml 文件中声明的 <authentication-manager> alias 。不要忘记注释掉 CustomJdbcDaoImpl 的声明——我们暂时不会使用它。

 

接下来,我们需要对 changePassword.jsp 做一些小的调整:

 

Html代码   收藏代码
  1. < h1 > Change Password </ h1 >   
  2. < form   method = "post" >   
  3.   < label   for = "oldpassword" > Old Password </ label > :  
  4.   < input   id = "oldpassword"   name = "oldpassword"    
  5.          size = "20"   maxlength = "50"   type = "password" />   
  6.   < br   />   
  7.   < label   for = "password" > New Password </ label > :  
  8.   < input   id = "password"   name = "password"   size = "20"    
  9.          maxlength = "50"   type = "password" />   
  10.   < br   />   

 最后,需要简单调整 AccountController 。将 @Autowired 引用 IChangePassword 的实现替换为:

 

Java代码   收藏代码
  1. @Autowired   
  2. private  UserDetailsManager userDetailsManager;  

 submitChangePasswordPage 方法也会更加简单了,因为要依赖的当前用户信息将会由 JdbcUserDetailsManager 为我们确定:

 

Java代码   收藏代码
  1. public  String submitChangePasswordPage( @RequestParam ( "oldpassword" )   
  2.        String oldPassword,   
  3.   @RequestParam ( "password" ) String newPassword) {  
  4.   userDetailsManager.changePassword(oldPassword, newPassword);  
  5.   SecurityContextHolder.clearContext();  
  6.   return   "redirect:home.do" ;  
  7. }  

 在这些修改完成后,你可以重启应用并尝试新的修改密码功能。

 

注意当你没有提供正确的密码时将会发生什么。试想一下会发生什么?并尝试思考怎样调整能使得对用户更友好。

 

尽管我们没有阐述 JdbcUserDetailsManager 提供的所有功能,但是可以看出它能很容易与简单的 JSP 页面结合在一起(当然要进行适当授权)以允许管理员来管理站点的用户——这对产品级别的应用是必要的。

猜你喜欢

转载自kongcodecenter.iteye.com/blog/1320010
今日推荐