spring security3.x学习(16)_JdbcUserDetailManager的使用
2013-09-20 14:53
429 查看
我们看一看UserDetailsService为我们提供了那些实现类。
![](https://img-blog.csdn.net/20130920145126703?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHN1bmRzdW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
里边还提供了一个名为JdbcuserDetailsManager的JdbcDaoImpl(UserDetailsService的子类)的实现类。那他究竟是如何扩展jdbcDaoImpl的呢?
![](https://img-blog.csdn.net/20130920145201468?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHN1bmRzdW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
他的类中,又定义了很多的SQL语句,而且添加了很多方法,很明显,他对JdbcDaoImpl进行了功能上的扩展。
书中提供了一些扩展的举例:
![](https://img-blog.csdn.net/20130920145212343?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHN1bmRzdW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
如果是这样的话,上次的修改密码的功能,它也帮助我们实现了,写到这,我们可以猜出来,其实配置它和配置上一个自定义的JdbcDaoImpl是一样的。
[align=left] <bean id="jdbcUserService" class="org.springframework.security.provisioning.JdbcUserDetailsManager" >[/align]
[align=left] <property name= "dataSource" ref="dataSource" />[/align]
[align=left] <property name="authenticationManager" ref="authenticationManager" />[/align]
[align=left] </bean >[/align]
[align=left]spring security配置:[/align]
[align=left] <authentication-manager alias="authenticationManager" >[/align]
[align=left] <authentication-provider user-service-ref="jdbcUserService" />[/align]
[align=left] </authentication-manager >[/align]
[align=left]这个配置,唯一一个优点区别的就是要在jdbcUserService中配置一下authenticationManager,那么为什么要设置这个属性呢?、我们通过查看源码就可以找到答案的:[/align]
[align=left]/* */ protected void initDao() throws ApplicationContextException[/align]
[align=left]/* */ {[/align]
/* 129 */ if (this. authenticationManager == null)
{
/* 130 */ this.logger.info( "No
authentication manager set. Reauthentication of users when changing passwords will not be performed.");
[align=left]/* */ }[/align]
[align=left]/* */[/align]
[align=left]/* 134 */ super.initDao();[/align]
[align=left]/* */ }[/align]
[align=left]
[/align]
[align=left]
[/align]
/* */ public void changePassword(String
oldPassword, String newPassword) throws AuthenticationException {
[align=left]/* 192 */ Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();[/align]
[align=left]/* */[/align]
[align=left]/* 194 */ if (currentUser == null)[/align]
[align=left]/* */ {[/align]
/* 196 */ throw new AccessDeniedException("Can't
change password as no Authentication object found in context for current user.");
[align=left]/* */ }[/align]
[align=left]/* */[/align]
[align=left]/* 200 */ String username = currentUser.getName();[/align]
[align=left]/* */[/align]
/* 203 */ if (this. authenticationManager != null)
{
/* 204 */ this.logger .debug("Reauthenticating
user '" + username + "' for password change request.");
[align=left]/* */[/align]
/* 206 */ this.authenticationManager .authenticate(new UsernamePasswordAuthenticationToken(username,
oldPassword));
[align=left]/* */ } else {[/align]
/* 208 */ this.logger.debug( "No
authentication manager set. Password won't be re-checked.");
[align=left]/* */ }[/align]
[align=left]/* */[/align]
/* 211 */ this.logger.debug( "Changing
password for user '" + username + "'");
[align=left]/* */[/align]
/* 213 */ getJdbcTemplate().update(this .changePasswordSql , new Object[]
{ newPassword, username });
[align=left]/* */[/align]
[align=left]/* 215 */ SecurityContextHolder.getContext().setAuthentication(createNewAuthentication(currentUser, newPassword));[/align]
[align=left]/* */[/align]
[align=left]/* 217 */ this.userCache.removeUserFromCache(username);[/align]
[align=left]/* */ }[/align]
[align=left]
[/align]
[align=left]我们可以推断出来,只有更改密码时会使用到,所以如果不设置authenticationManager属性的话,更改密码会失败的。[/align]
[align=left]spring mvc中是这样修改密码的:[/align]
[align=left] @RequestMapping(value= "/account/changePassword.do",method=RequestMethod.POST)[/align]
public String submitChangePasswordPage(@RequestParam ("password" )
String newPassword) {
[align=left] Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();[/align]
[align=left]
[/align]
[align=left] String username = principal.toString();[/align]
if (principal instanceof UserDetails)
{
[align=left] username = ((UserDetails)principal).getUsername();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] changePasswordDao.changePassword( username, newPassword);[/align]
[align=left] SecurityContextHolder. clearContext();[/align]
[align=left] [/align]
[align=left] return "redirect:home.do" ;[/align]
[align=left] }[/align]
[align=left]那么。这里边涉及到了一个叫做SecurityContextHolder的对象,这个对象是做什么用的呢?[/align]
[align=left]它可以获取认证信息(通过认证流程以后会返回一个新的Authentication,前几次我们已经说过了):SecurityContextHolder.getContext().getAuthentication();[/align]
[align=left]返回Authentication然后通过getPrincipal()方法获取安全实体(我们把它想象成安全对像就行),返回值是Object类型,也就是说,他可以使任何对象类型,一般来说是UserDetails,但有时也是username(这个一般是UserDetails中的一部分).[/align]
[align=left]获取用户名完成以后,可以通过我们前边定义好的修改密码类(JdbcUserDetailsManager)实现修改密码。[/align]
接着又有一句话叫做:SecurityContextHolder. clearContext();
那么它完成了什么功能呢,很遗憾,我再电子书和官方的帮助文档中都没有找到,所以我查询了spring security API:
![](https://img-blog.csdn.net/20130920145258968?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHN1bmRzdW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
就是说,当我调用这个方法以后,我们将清除Security 上下文中的所有当前线程中的值(看起来挺好用的)。
里边还提供了一个名为JdbcuserDetailsManager的JdbcDaoImpl(UserDetailsService的子类)的实现类。那他究竟是如何扩展jdbcDaoImpl的呢?
他的类中,又定义了很多的SQL语句,而且添加了很多方法,很明显,他对JdbcDaoImpl进行了功能上的扩展。
书中提供了一些扩展的举例:
如果是这样的话,上次的修改密码的功能,它也帮助我们实现了,写到这,我们可以猜出来,其实配置它和配置上一个自定义的JdbcDaoImpl是一样的。
[align=left] <bean id="jdbcUserService" class="org.springframework.security.provisioning.JdbcUserDetailsManager" >[/align]
[align=left] <property name= "dataSource" ref="dataSource" />[/align]
[align=left] <property name="authenticationManager" ref="authenticationManager" />[/align]
[align=left] </bean >[/align]
[align=left]spring security配置:[/align]
[align=left] <authentication-manager alias="authenticationManager" >[/align]
[align=left] <authentication-provider user-service-ref="jdbcUserService" />[/align]
[align=left] </authentication-manager >[/align]
[align=left]这个配置,唯一一个优点区别的就是要在jdbcUserService中配置一下authenticationManager,那么为什么要设置这个属性呢?、我们通过查看源码就可以找到答案的:[/align]
[align=left]/* */ protected void initDao() throws ApplicationContextException[/align]
[align=left]/* */ {[/align]
/* 129 */ if (this. authenticationManager == null)
{
/* 130 */ this.logger.info( "No
authentication manager set. Reauthentication of users when changing passwords will not be performed.");
[align=left]/* */ }[/align]
[align=left]/* */[/align]
[align=left]/* 134 */ super.initDao();[/align]
[align=left]/* */ }[/align]
[align=left]
[/align]
[align=left]
[/align]
/* */ public void changePassword(String
oldPassword, String newPassword) throws AuthenticationException {
[align=left]/* 192 */ Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();[/align]
[align=left]/* */[/align]
[align=left]/* 194 */ if (currentUser == null)[/align]
[align=left]/* */ {[/align]
/* 196 */ throw new AccessDeniedException("Can't
change password as no Authentication object found in context for current user.");
[align=left]/* */ }[/align]
[align=left]/* */[/align]
[align=left]/* 200 */ String username = currentUser.getName();[/align]
[align=left]/* */[/align]
/* 203 */ if (this. authenticationManager != null)
{
/* 204 */ this.logger .debug("Reauthenticating
user '" + username + "' for password change request.");
[align=left]/* */[/align]
/* 206 */ this.authenticationManager .authenticate(new UsernamePasswordAuthenticationToken(username,
oldPassword));
[align=left]/* */ } else {[/align]
/* 208 */ this.logger.debug( "No
authentication manager set. Password won't be re-checked.");
[align=left]/* */ }[/align]
[align=left]/* */[/align]
/* 211 */ this.logger.debug( "Changing
password for user '" + username + "'");
[align=left]/* */[/align]
/* 213 */ getJdbcTemplate().update(this .changePasswordSql , new Object[]
{ newPassword, username });
[align=left]/* */[/align]
[align=left]/* 215 */ SecurityContextHolder.getContext().setAuthentication(createNewAuthentication(currentUser, newPassword));[/align]
[align=left]/* */[/align]
[align=left]/* 217 */ this.userCache.removeUserFromCache(username);[/align]
[align=left]/* */ }[/align]
[align=left]
[/align]
[align=left]我们可以推断出来,只有更改密码时会使用到,所以如果不设置authenticationManager属性的话,更改密码会失败的。[/align]
[align=left]spring mvc中是这样修改密码的:[/align]
[align=left] @RequestMapping(value= "/account/changePassword.do",method=RequestMethod.POST)[/align]
public String submitChangePasswordPage(@RequestParam ("password" )
String newPassword) {
[align=left] Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();[/align]
[align=left]
[/align]
[align=left] String username = principal.toString();[/align]
if (principal instanceof UserDetails)
{
[align=left] username = ((UserDetails)principal).getUsername();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] changePasswordDao.changePassword( username, newPassword);[/align]
[align=left] SecurityContextHolder. clearContext();[/align]
[align=left] [/align]
[align=left] return "redirect:home.do" ;[/align]
[align=left] }[/align]
[align=left]那么。这里边涉及到了一个叫做SecurityContextHolder的对象,这个对象是做什么用的呢?[/align]
[align=left]它可以获取认证信息(通过认证流程以后会返回一个新的Authentication,前几次我们已经说过了):SecurityContextHolder.getContext().getAuthentication();[/align]
[align=left]返回Authentication然后通过getPrincipal()方法获取安全实体(我们把它想象成安全对像就行),返回值是Object类型,也就是说,他可以使任何对象类型,一般来说是UserDetails,但有时也是username(这个一般是UserDetails中的一部分).[/align]
[align=left]获取用户名完成以后,可以通过我们前边定义好的修改密码类(JdbcUserDetailsManager)实现修改密码。[/align]
接着又有一句话叫做:SecurityContextHolder. clearContext();
那么它完成了什么功能呢,很遗憾,我再电子书和官方的帮助文档中都没有找到,所以我查询了spring security API:
就是说,当我调用这个方法以后,我们将清除Security 上下文中的所有当前线程中的值(看起来挺好用的)。
相关文章推荐
- spring security3.x学习(16)_JdbcUserDetailManager的使用
- spring security3.x学习(14)_关系型数据库使用的UserDetailsService(JdbcDaoImpl)
- 第二章:Improving On User Commands--16.使用已删除的文档
- Controller的构造函数使用UserManager.FindById(User.Identity.GetUserId())导致错误的处理
- SpringMVC(16):使用springmvc+spring+jdbc 优化订单管理系统的示例(多条件查询供应商列表功能实现)
- mybatis使用jdbc username 获取到window账户的用户名
- Can't User UserProfileManager.GetUserProfile Get User Userprofile In Web Service,Error:System.ArgumentNullException: Value Cannot Be Null.(不能在Webservice中使用UserProfileManager的GetUserProfile得到用户配置,报错:System.ArgumentNullException: 值不能为空。)
- java 中jdbc的使用练习-错误 mysql access denied for user odbc @localhost
- C#三层架构的UserManager类(注册登录使用)
- spring security3.x学习(14)_关系型数据库使用的UserDetailsService(JdbcDaoImpl)
- 第二章:Improving On User Commands--16.使用已删除的文档
- JDBC为什么要使用PreparedStatemen…
- unity easymobile GameServiceManager.UserAuthenticated
- JAVA/JdbcManager
- Java使用JDBC连接mysql数据库并封装数据
- JDBC使用线程池与连接池,释放连接后,连接池不为空,使得Connection无法创建
- 使用TCP Keep-alive与TCP_USER_TIMEOUT机制判断通信对端是否存活
- 使用 jQuery Mobile 与 HTML5 开发 Web App —— 16 HTML5 Web Storage
- ChatScript 5 Advanced User Manual -- 6 Esoterica and Fine Detail
- 回发或回调参数无效。在配置中使用 或在页面中使用 启用了事件验证。出于安全目的,此功能验证回发或回调事件的参数是否来源于最初呈现这些事件的服务器控件。如果数据有效并且是预期的,则使用 ClientScriptManager.RegisterForEventValidation 方法来注册回发或回调数据以进行验证。