《Spring Security3》第四章第一部分翻译下(自定义的UserDetailsService)
2014-12-18 16:31
381 查看
实现自定义的JDBC UserDetailsService
正如在前面章节中的那个练习,我们将以基本的JdbcDaoImpl作为起点,将其进行扩展以支持修改密码功能。
Java代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
public class CustomJdbcDaoImpl extends JdbcDaoImpl implements
IChangePassword {
public void changePassword(String username, String password) {
getJdbcTemplate()
update("UPDATE USERS SET PASSWORD = ? WHERE USERNAME = ?",
password, username);
}
}
你可以看到这个类扩展了JdbcDaoImpl默认类,提供了按照用户请求更新数据库中密码的功能。我们使用标准的Spring JDBC模板完成这个功能。
Xml代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
<bean id="jdbcUserService"
class="com.packtpub.springsecurity.security.CustomJdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
同样的,dataSource 的Bean引用指向了<embedded-database>声明,我们使用这个声明来安装HSQL内存数据库。
你会发现自定义的UserDetailsService允许我们与数据库直接交互。在接下来的例子中,我们将使用这个功能来扩展UserDetailsService的基本功能。在使用Spring Security的复杂应用中,这种类型的个性化是很常见的。
基于JDBC的内置用户管理
正如上面简单JdbcDaoImpl扩展所描述的那样,开发人员可能会扩展这个类,但同时也会保留基本的功能。而我们要实现更复杂功能时,如用户注册(online store所必须的)与用户管理功能、站点的管理员创建用户、更新密码等,又会怎样呢?
尽管这些功能借助JDBC语句都能相对容易的实现,但是Spring Security还是为我们提供了内置的功能以支持对数据库里的用户进行创建、读取、更新和删除的操作。这对简单的系统来说是很有用的,同时也为构建自定义需求的用户提供了很好的起点。
实现类o.s.s.provisioning.JdbcUserDetailsManager扩展了JdbcDaoImpl的功能,提供了一些很有用的与用户相关的方法,这些方法的一部分在o.s.s.provisioning.UserDetailsManager接口中进行了定义:
正如你所见,JdbcUserDetailsManager的changePassword方法正好满足了我们CustomJdbcDaoImpl的不足——在修改之前,它会检验用户已存在密码。让我们看一下将CustomJdbcDaoImpl替换为JdbcUserDetailsManager需要怎样的配置步骤。
首先,我们需要在dogstore-base.xml中声明JdbcUserDetailsManager bean:
Xml代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
<bean id="jdbcUserService"
class="org.springframework.security
.provisioning.JdbcUserDetailsManager">
<property name="dataSource" ref="dataSource"/>
<property name="authenticationManager"
ref="authenticationManager"/>
</bean>
对AuthenticationManager的引用要匹配我们之前dogstore-security.xml文件中声明的<authentication-manager>的alias。不要忘记注释掉CustomJdbcDaoImpl的声明——我们暂时不会使用它。
接下来,我们需要对changePassword.jsp做一些小的调整:
Html代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
<h1>Change Password</h1>
<form method="post">
<label for="oldpassword">Old Password</label>:
<input id="oldpassword" name="oldpassword"
size="20" maxlength="50" type="password"/>
<br />
<label for="password">New Password</label>:
<input id="password" name="password" size="20"
maxlength="50" type="password"/>
<br />
最后,需要简单调整AccountController。将@Autowired引用IChangePassword的实现替换为:
Java代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
@Autowired
private UserDetailsManager userDetailsManager;
submitChangePasswordPage方法也会更加简单了,因为要依赖的当前用户信息将会由JdbcUserDetailsManager为我们确定:
Java代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
public String submitChangePasswordPage(@RequestParam("oldpassword")
String oldPassword,
@RequestParam("password") String newPassword) {
userDetailsManager.changePassword(oldPassword, newPassword);
SecurityContextHolder.clearContext();
return "redirect:home.do";
}
在这些修改完成后,你可以重启应用并尝试新的修改密码功能。
注意当你没有提供正确的密码时将会发生什么。试想一下会发生什么?并尝试思考怎样调整能使得对用户更友好。
尽管我们没有阐述JdbcUserDetailsManager提供的所有功能,但是可以看出它能很容易与简单的JSP页面结合在一起(当然要进行适当授权)以允许管理员来管理站点的用户——这对产品级别的应用是必要的。
正如在前面章节中的那个练习,我们将以基本的JdbcDaoImpl作为起点,将其进行扩展以支持修改密码功能。
创建一个自定义的JDBC UserDetailsService
在com.packtpub.springsecurity.security包下创建如下的类:Java代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
public class CustomJdbcDaoImpl extends JdbcDaoImpl implements
IChangePassword {
public void changePassword(String username, String password) {
getJdbcTemplate()
update("UPDATE USERS SET PASSWORD = ? WHERE USERNAME = ?",
password, username);
}
}
你可以看到这个类扩展了JdbcDaoImpl默认类,提供了按照用户请求更新数据库中密码的功能。我们使用标准的Spring JDBC模板完成这个功能。
为自定义的JDBC UserDetailsService添加Spring bean声明
在dogstore-base.xml配置文件中,添加如下的Spring Bean声明:Xml代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
<bean id="jdbcUserService"
class="com.packtpub.springsecurity.security.CustomJdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
同样的,dataSource 的Bean引用指向了<embedded-database>声明,我们使用这个声明来安装HSQL内存数据库。
你会发现自定义的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) | 修改当期登录用户的密码。为了使得操作成功,用户必须提供正确的当期密码。 |
首先,我们需要在dogstore-base.xml中声明JdbcUserDetailsManager bean:
Xml代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
<bean id="jdbcUserService"
class="org.springframework.security
.provisioning.JdbcUserDetailsManager">
<property name="dataSource" ref="dataSource"/>
<property name="authenticationManager"
ref="authenticationManager"/>
</bean>
对AuthenticationManager的引用要匹配我们之前dogstore-security.xml文件中声明的<authentication-manager>的alias。不要忘记注释掉CustomJdbcDaoImpl的声明——我们暂时不会使用它。
接下来,我们需要对changePassword.jsp做一些小的调整:
Html代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
<h1>Change Password</h1>
<form method="post">
<label for="oldpassword">Old Password</label>:
<input id="oldpassword" name="oldpassword"
size="20" maxlength="50" type="password"/>
<br />
<label for="password">New Password</label>:
<input id="password" name="password" size="20"
maxlength="50" type="password"/>
<br />
最后,需要简单调整AccountController。将@Autowired引用IChangePassword的实现替换为:
Java代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
@Autowired
private UserDetailsManager userDetailsManager;
submitChangePasswordPage方法也会更加简单了,因为要依赖的当前用户信息将会由JdbcUserDetailsManager为我们确定:
Java代码
![](http://lengyun3566.iteye.com/images/icon_star.png)
public String submitChangePasswordPage(@RequestParam("oldpassword")
String oldPassword,
@RequestParam("password") String newPassword) {
userDetailsManager.changePassword(oldPassword, newPassword);
SecurityContextHolder.clearContext();
return "redirect:home.do";
}
在这些修改完成后,你可以重启应用并尝试新的修改密码功能。
注意当你没有提供正确的密码时将会发生什么。试想一下会发生什么?并尝试思考怎样调整能使得对用户更友好。
尽管我们没有阐述JdbcUserDetailsManager提供的所有功能,但是可以看出它能很容易与简单的JSP页面结合在一起(当然要进行适当授权)以允许管理员来管理站点的用户——这对产品级别的应用是必要的。
相关文章推荐
- 自定义 Spring Security 4 的UserDetailsService和UserDetails
- 基于数据库自定义UserDetailsService实现Spring security认证
- 《Spring Security3》第四章第一部分翻译上(数据库管理信息)
- spring security3.x学习(14)_关系型数据库使用的UserDetailsService(JdbcDaoImpl)
- MS CRM 2011的自定义和开发(10)——CRM web服务介绍(第一部分)——IDiscoveryService
- Prism4文档翻译(第四章 第一部分)
- Spring Security 4.1.3 实现UserDetailsService,实现登陆验证、会话管理
- SPRING IN ACTION 第4版笔记-第九章Securing web applications-008-使用非关系型数据库时如何验证用户(自定义UserService)
- acegi security实践教程—定制userDetailsService
- Prism4文档翻译(第四章 第一部分)
- spring security3.x学习(14)_关系型数据库使用的UserDetailsService(JdbcDaoImpl)
- Encog3Java-User.pdf翻译:第四章 使用Java构建神经网络
- 详解Spring Security进阶身份认证之UserDetailsService(附源码)
- PreAuthenticatedGrantedAuthoritiesUserDetailsService/DelegatingFilterProxy
- 第四章 自定义user
- Spring security +Hibernate+UserDetailsService认证
- 《Spring Security3》第六章第一部分翻译(自定义安全过滤器)
- 简单继承UserDetailsService
- 关于Spring security中自定义UserDetailService无法注入DAO的问题
- SpringSecurity4使用UserDetailsService时无法注入数据库持久层的service、dao