先說一下AuthConfig.java Spring Security的主要配置文件之一 AuthConfig css
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 }
1、configur方法 基本配置html
No | Source | Comment |
L1 | @Configuration | 這個就是java形式的bean spring3.0之後 容許以 @Configuration 註解來代替XML形式的bean |
L2 | @EnableWebSecurity | 用這個註解開啓 spring security配置驗證開啓 |
L3 | WebSecurityConfigurerAdapter | 這個須要咱們繼承WebSecurityConfigurerAdapter適配器且重寫 configure 函數 來實現訪問的控制(那些訪問/資源 須要哪些權限)和登陸的驗證(數據庫驗證/內存驗證)java |
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設定git |
2、globalAuthConfig方法 認證github
先說L38 這行注掉的 是內存認證模式 意思是建立了一個 名爲user 密碼 爲password的用戶spring
而後是 L37 這也是認證核心數據庫
先看一下這個 傳入參數的的構成 也就是 AuthUserService 類api
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函數session
關於 getAuthorityByLoginId 好說的基本上就是 當前用戶的權限app
而後是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地址
(完)