Spring Security身份認證之UserDetailsService
阿新 • • 發佈:2019-01-04
之前我們採用了配置檔案的方式從資料庫中讀取使用者進行登入。雖然該方式的靈活性相較於靜態賬號密碼的方式靈活了許多,但是將資料庫的結構暴露在明顯的位置上,絕對不是一個明智的做法。本文通過Java程式碼實現UserDetailsService介面來實現身份認證。
驗證身份就是載入響應的UserDetails,看看是否和使用者輸入的賬號、密碼、許可權等資訊匹配。此步驟由實現AuthenticationProvider的DaoAuthenticationProvider(它利用UserDetailsService驗證使用者名稱、密碼和授權)處理。包含 GrantedAuthority 的 UserDetails物件在構建 Authentication物件時填入資料。
1.2 配置UserDetailsService
1.2.3 啟動應用伺服器,只要使用者名稱和密碼不全是favccxx,就會產生下面的錯誤。
使用者名稱和密碼都輸入favccxx,則登陸成功
1.3 跟蹤UserDetailsService。
身份認證的呼叫流程圖如下,使用者可下載Spring Security原始碼跟蹤除錯。
1.1 UserDetailsService在身份認證中的作用
Spring Security中進行身份驗證的是AuthenticationManager介面,ProviderManager是它的一個預設實現,但它並不用來處理身份認證,而是委託給配置好的AuthenticationProvider,每個AuthenticationProvider會輪流檢查身份認證。檢查後或者返回Authentication物件或者丟擲異常。驗證身份就是載入響應的UserDetails,看看是否和使用者輸入的賬號、密碼、許可權等資訊匹配。此步驟由實現AuthenticationProvider的DaoAuthenticationProvider(它利用UserDetailsService驗證使用者名稱、密碼和授權)處理。包含 GrantedAuthority 的 UserDetails物件在構建 Authentication物件時填入資料。
1.2 配置UserDetailsService
1.2.1 更改Spring-Security.xml中身份的方式,使用自定義的UserDetailsService。
<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,就會產生下面的錯誤。
使用者名稱和密碼都輸入favccxx,則登陸成功
1.3 跟蹤UserDetailsService。
身份認證的呼叫流程圖如下,使用者可下載Spring Security原始碼跟蹤除錯。