spring security3.x学习(16)_JdbcUserDetailManager的使用

本文为转载学习java

原来你连接:http://blog.csdn.net/dsundsun/article/details/11847279spring

咱们看一看UserDetailsService为咱们提供了那些实现类。安全

里边还提供了一个名为JdbcuserDetailsManager的JdbcDaoImpl(UserDetailsService的子类)的实现类。那他到底是如何扩展jdbcDaoImpl的呢?mvc

他的类中,又定义了不少的SQL语句,并且添加了不少方法,很明显,他对JdbcDaoImpl进行了功能上的扩展。app

书中提供了一些扩展的举例:ide

若是是这样的话,上次的修改密码的功能,它也帮助咱们实现了,写到这,咱们能够猜出来,其实配置它和配置上一个自定义的JdbcDaoImpl是同样的。学习

  <bean id="jdbcUserService" class="org.springframework.security.provisioning.JdbcUserDetailsManager" >
        <property name= "dataSource" ref="dataSource" />
        <property name="authenticationManager" ref="authenticationManager" />
  </bean >

spring security配置:this

<authentication-manager alias="authenticationManager" >
        <authentication-provider user-service-ref="jdbcUserService" />
</authentication-manager >

这个配置,惟一一个优势区别的就是要在jdbcUserService中配置一下authenticationManager,那么为何要设置这个属性呢?咱们经过查看源码就能够找到答案的:spa

/*     */    protected void initDao() throws ApplicationContextException
/*     */    {
/* 129 */     if (this. authenticationManager == null) {
/* 130 */       this.logger.info( "No authentication manager set. Reauthentication of users when changing passwords will not be performed.");
/*     */      }
/*     */
/* 134 */     super.initDao();
/*     */    }


/*     */    public void changePassword(String oldPassword, String newPassword) throws AuthenticationException {
/* 192 */     Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
/*     */
/* 194 */     if (currentUser == null)
/*     */      {
/* 196 */       throw new AccessDeniedException("Can't change password as no Authentication object found in context for current user.");
/*     */      }
/*     */
/* 200 */     String username = currentUser.getName();
/*     */
/* 203 */     if (this. authenticationManager != null) {
/* 204 */       this.logger .debug("Reauthenticating user '" + username + "' for password change request.");
/*     */
/* 206 */       this.authenticationManager .authenticate(new UsernamePasswordAuthenticationToken(username, oldPassword));
/*     */      } else {
/* 208 */       this.logger.debug( "No authentication manager set. Password won't be re-checked.");
/*     */      }
/*     */
/* 211 */     this.logger.debug( "Changing password for user '" + username + "'");
/*     */
/* 213 */     getJdbcTemplate().update(this .changePasswordSql , new Object[] { newPassword, username });
/*     */
/* 215 */     SecurityContextHolder.getContext().setAuthentication(createNewAuthentication(currentUser, newPassword));
/*     */
/* 217 */     this.userCache.removeUserFromCache(username);
/*     */    }

咱们能够推断出来,只有更改密码时会使用到,因此若是不设置authenticationManager属性的话,更改密码会失败的。.net

spring mvc中是这样修改密码的:

    @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" ;
    }

那么。这里边涉及到了一个叫作SecurityContextHolder的对象,这个对象是作什么用的呢?

它能够获取认证信息(经过认证流程之后会返回一个新的Authentication,前几回咱们已经说过了):SecurityContextHolder.getContext().getAuthentication();

返回Authentication而后经过getPrincipal()方法获取安全实体(咱们把它想象成安全对像就行),返回值是Object类型,也就是说,他可使任何对象类型,通常来讲是UserDetails,但有时也是username(这个通常是UserDetails中的一部分).

获取用户名完成之后,能够经过咱们前边定义好的修改密码类(JdbcUserDetailsManager)实现修改密码。

接着又有一句话叫作:SecurityContextHolder. clearContext(); 那么它完成了什么功能呢,很遗憾,我再电子书和官方的帮助文档中都没有找到,因此我查询了spring security API:

就是说,当我调用这个方法之后,咱们将清除Security 上下文中的全部当前线程中的值(看起来挺好用的)。

相关文章
相关标签/搜索