在上一篇Spring Security身份認證博文中,咱們採用了配置文件的方式從數據庫中讀取用戶進行登陸。雖然該方式的靈活性相較於靜態帳號密碼的方式靈活了許多,可是將數據庫的結構暴露在明顯的位置上,絕對不是一個明智的作法。本文經過Java代碼實現UserDetailsService接口來實現身份認證。java
1.1 UserDetailsService在身份認證中的做用
spring
Spring Security中進行身份驗證的是AuthenticationManager接口,ProviderManager是它的一個默認實現,但它並不用來處理身份認證,而是委託給配置好的AuthenticationProvider,每一個AuthenticationProvider會輪流檢查身份認證。檢查後或者返回Authentication對象或者拋出異常。數據庫
驗證身份就是加載響應的UserDetails,看看是否和用戶輸入的帳號、密碼、權限等信息匹配。此步驟由實現AuthenticationProvider的DaoAuthenticationProvider(它利用UserDetailsService驗證用戶名、密碼和受權)處理。包含 GrantedAuthority 的 UserDetails對象在構建 Authentication對象時填入數據。apache
1.2 配置UserDetailsService服務器
1.2.1 更改Spring-Security.xml中身份的方式,使用自定義的UserDetailsService。ide
<security:authentication-manager>
<security:authentication-provider user-service-ref="favUserDetailService">
</security:authentication-provider>
</security:authentication-manager>
<bean id="favUserDetailService" class="com.favccxx.favsecurity.security.FavUserDetailService" />
1.2.2 新建FavUserDetailsService.java,實現UserDetailsService接口。爲了下降學習的難度,這裏並無與數據庫進行集成,而是採用模擬從數據庫中獲取用戶的方式進行身份驗證。示例代碼以下:學習
package com.favccxx.favsecurity.security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class FavUserDetailService implements UserDetailsService {
private static final Logger logger = LogManager.getLogger(FavUserDetailService.class);
/**
* 根據用戶名獲取用戶 - 用戶的角色、權限等信息
*/
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
UserDetails userDetails = null;
try {
com.favccxx.favsecurity.pojo.User favUser = new com.favccxx.favsecurity.pojo.User();
favUser.setUsername("favccxx");
favUser.setPassword("favccxx");
Collection<GrantedAuthority> authList = getAuthorities();
userDetails = new User(username, favUser.getPassword().toLowerCase(),true,true,true,true,authList);
} catch (Exception e) {
e.printStackTrace();
}
return userDetails;
}
/**
* 獲取用戶的角色權限,爲了下降實驗的難度,這裏去掉了根據用戶名獲取角色的步驟
* @param
* @return
*/
private Collection<GrantedAuthority> getAuthorities(){
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
authList.add(new SimpleGrantedAuthority("ROLE_USER"));
authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return authList;
}
}
1.2.3 啓動應用服務器,只要用戶名和密碼不全是favccxx,就會產生下面的錯誤。spa
用戶名和密碼都輸入favccxx,則登錄成功調試
1.3 跟蹤UserDetailsService。xml
身份認證的調用流程圖以下,用戶可下載Spring Security源代碼跟蹤調試。
1.4 如不能正常運行,點這裏看看源代碼吧。