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 上下文中的全部當前線程中的值(看起來挺好用的)。

相關文章
相關標籤/搜索