spring boot系列--spring security (基於數據庫)登錄和權限控制


先說一下AuthConfig.java Spring Security的主要配置文件之一 AuthConfig 

復制代碼
 1 @Configuration
 2 @EnableWebSecurity
 3 public class AuthConfig extends WebSecurityConfigurerAdapter {
 4     @Override
 5     protected void configure(HttpSecurity httpSecurity) throws Exception {
 6         httpSecurity.authorizeRequests()
 7         .antMatchers("/css/**","/staic/**", "/js/**","/images/**").permitAll()
 8         .antMatchers("/", "/login","/session_expired").permitAll()
 9            .and()
10      .formLogin()
11         .loginPage("/login")
12         .defaultSuccessUrl("/main_menu")
13         .failureUrl("/loginError")
14         .usernameParameter("txtUserCd")
15         .passwordParameter("txtUserPwd")
16         .permitAll()
17         .and()
18         .logout()
19         .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
20         .logoutSuccessUrl("/")
21         .deleteCookies("JSESSIONID")
22         .invalidateHttpSession(true)
23         .permitAll()
24         .and()
25         .sessionManagement()
26         .invalidSessionUrl("/session_expired")
27         .maximumSessions(1)
28         .maxSessionsPreventsLogin(true)
29         .expiredUrl("/session_expired");
30         httpSecurity.logout().permitAll();
31 
32     }
33     
34      @Autowired
35      AuthUserService authUserService;
36     public void globalAuthConfig(AuthenticationManagerBuilder auth) throws Exception {
37         auth.userDetailsService(authUserService);
38       //auth.inMemoryAuthentication().withUser("user").password("password");
39     }
40     /*@Configuration
41     protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
42         @Autowired
43         AuthUserService authUserService;
44     
45         @Override
46         public void init(AuthenticationManagerBuilder auth) throws Exception {
47             //auth.inMemoryAuthentication().withUser("user").password("password");
48             auth.userDetailsService(authUserService);
49         }
50     }*/
51 }
復制代碼

一、configur方法 基本配置

No Source Comment
L1 @Configuration 這個就是java形式的bean spring3.0以后 允許以 @Configuration 注解來代替XML形式的bean
L2 @EnableWebSecurity 用這個注解開啟 spring security配置驗證開啟
L3 WebSecurityConfigurerAdapter 這個需要我們繼承WebSecurityConfigurerAdapter適配器且重寫

 configure 函數 來實現訪問的控制(那些訪問/資源 需要哪些權限)和登錄的驗證(數據庫驗證/內存驗證)

L6 authorizeRequests() 通過authorizeRequests()配下的子函來完成訪問/授權 配置
L7,8 antMatchers/permitAll antMatchers里配置的資源是可以被所有用戶訪問(permitAll)的
L9 and() 類似於結束標簽
L10 formLogin 通過formLogin()配下的函數對登錄form進行配置
L11 loginPage 設置登錄頁面
L12 defaultSuccessUrl 默認登錄成功跳轉地址
L13 failureUrl 默認登錄失敗跳轉地址
L14,15 usernameParameter
passwordParameter
用戶名密碼驗證用 *這里的參數要和畫面上控件名保持一致
L18  logout() 通過logout()配下的函數對注銷進行配置
L19 .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 設置注銷用的請求URL
L20 logoutSuccessUrl 設置注銷成功后的跳轉URL
L21 deleteCookies 消除Cookie
L22 invalidateHttpSession 銷毀Session
L25 sessionManagement 通過sessionManagement配下的函數對session配置
L27 maximumSessions 同一用戶session上限設定 *比如同一個用戶 多次登錄
L28 maxSessionsPreventsLogin maximumSessions設定的上限啟用 * 超出報錯
L29 expiredUrl

超過session上限跳轉URL設定

 

 二、globalAuthConfig方法 認證

先說L38 這行注掉的 是內存認證模式  意思是創建了一個 名為user 密碼 為password的用戶

然后是 L37 這也是認證核心

先看一下這個 傳入參數的的構成 也就是 AuthUserService 類

復制代碼
 1 @Service
 2 public class AuthUserService implements UserDetailsService{
 3 
 4     @Autowired
 5     MstUsersMapper mstUsersMapper;
 6     
 7     @Override
 8     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 9         Users users =mstUsersMapper.selectByPrimaryKey(username);
10         if(users == null) {
11             throw new UsernameNotFoundException("User not found for name:"+username);
12         }
13         return new AuthUser(users);
14     }
15     
16     public String getAuthorityByLoginId(String loginId ){
17         //Map<String,String> authKindMap = new HashMap<String,String>();
18         String auth = mstUsersMapper.selectAuthorityByLoginId(loginId); 
19         return auth;
20     }
21 }
復制代碼

可以看到我們是 實現了UserDetailsService 然后重寫了一個loadUserByUsername和追加了一個 getAuthorityByLoginId函數

關於 getAuthorityByLoginId 好說的基本上就是 當前用戶的權限

然后是loadUserByUsername

可以通過名字基本上可以看的出是 通過name 取user 的信息 實際上也是這樣 這里並不判斷你輸的密碼對不對 主要是

判斷你輸入的用戶名在數據庫里存不存在 不存在 報錯 扔出 存在 實例化一個 AuthUser 返回

這個AuthUser 類也很重要 實現了UserDetails  如下

復制代碼
 1 public class AuthUser implements UserDetails {
 2     private static final long serialVersionUID = 1L;
 3     
 4     private String userId;
 5     private String loginId;
 6     private String password;
 7     private String authorityKind;
 8     public AuthUser(Users users) {
 9         super();
10         this.userId = users.getUserId();
11         this.loginId = users.getLoginId();
12         this.password = users.getPassword();
13         this.authorityKind = users.getAuthorityKind();
14     }
15 
16     @Override
17     public Collection<GrantedAuthority> getAuthorities() {
18         List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
19         list.add(new SimpleGrantedAuthority(authorityKind));
20         return list;
21     }
22 
23     @Override
24     public String getPassword() {
25         return password;
26     }
27 
28     @Override
29     public String getUsername() {
30         return loginId;
31     }
32 
33     @Override
34     public boolean isAccountNonExpired() {
35         return true;
36     }
37 
38     @Override
39     public boolean isAccountNonLocked() {
40         return true;
41     }
42 
43     @Override
44     public boolean isCredentialsNonExpired() {
45         return true;
46     }
47 
48     @Override
49     public boolean isEnabled() {
50         return true;
51     }
復制代碼

 這里的幾個點要注意一下

L17 getAuthorities 它返回了一個權限集合 這個集合是和你在畫面側用的hasAnyAuthority('ROLE_USER','ROLE_ADMIN') 這個函數相呼應的

換言之你之所以能在畫面側如上那樣寫也是因為你在這里吧把當前用戶的權限set進去了

 

然后看一下我們實現的 UserDetails這個父類,如下官網文檔給的信息.

No Modifier and Type Method and Description
1 java.util.Collection<? extends GrantedAuthority> getAuthorities()
Returns the authorities granted to the user.
2 java.lang.String getPassword()
Returns the password used to authenticate the user.
3 java.lang.String getUsername()
Returns the username used to authenticate the user.
4 boolean isAccountNonExpired()
Indicates whether the user's account has expired.
5 boolean isAccountNonLocked()
Indicates whether the user is locked or unlocked.
6 boolean isCredentialsNonExpired()
Indicates whether the user's credentials (password) has expired.
7 boolean isEnabled()
Indicates whether the user is enabled or disabled.

 

 前3個應該不用說了,從第四個開始說一下

isAccountNonExpired():當前賬號是否已經過期

isAccountNonLocked():當前賬號是否被鎖

isCredentialsNonExpired():當前賬號證書(密碼)是否過期

isEnabled():當前賬號是否被禁用

都要給設成true 否則登錄會報出來

還有實現一個UserDetailsService類如下

復制代碼
 1 @Service
 2 public class AuthUserService implements UserDetailsService{
 3 
 4     @Autowired
 5     MstUsersMapper mstUsersMapper;
 6     
 7     @Override
 8     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 9         Users users =mstUsersMapper.selectByPrimaryKey(username);
10         if(users == null) {
11             throw new UsernameNotFoundException("User not found for name:"+username);
12         }
13         return new AuthUser(users);
14     }
15     
16     public String getAuthorityByLoginId(String loginId ){
17         //Map<String,String> authKindMap = new HashMap<String,String>();
18         String auth = mstUsersMapper.selectAuthorityByLoginId(loginId); 
19         return auth;
20     }
21 }
復制代碼
如你看到那樣loadUserByUsername這函數並不做密碼驗證只是拿username取用戶信息,當然取不到報錯
取到交給AuthUser,然后spring boot 自己再去判斷密碼,以及前面說的那個幾個check
剩下的就是 Controller這個就沒有特別要說的到git上看代碼就完了
最后貼一下執行效果圖及git地址

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM