一、只進行用戶驗證,不驗證密碼(UserDetailsService)
1、導入security依賴(在前端html頁面進行一些判斷 需導入xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4")
1 <dependency>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-security</artifactId>
4 </dependency>
5
6 <dependency>
7 <groupId>org.thymeleaf.extras</groupId>
8 <artifactId>thymeleaf-extras-springsecurity5</artifactId>
9 <version>3.0.4.RELEASE</version>
10 </dependency>
2、配置安全認證類
1 import org.springframework.beans.factory.annotation.Autowired; 2 import org.springframework.context.annotation.Bean; 3 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 4 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 5 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 8 import org.springframework.security.core.userdetails.UserDetailsService; 9 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 10 import org.springframework.security.crypto.password.PasswordEncoder; 11 import top.xiaoyl.service.CustomUserDetailService; 12
13 @EnableWebSecurity 14 @EnableGlobalMethodSecurity(prePostEnabled = true) 15 public class MySecurityConfig extends WebSecurityConfigurerAdapter { 16
17 @Override 18 protected void configure(HttpSecurity http) throws Exception { 19 //super.configure(http); 20 //定制請求的授權規則
21 http.authorizeRequests().antMatchers("/admin/**","/js/**","/css/**","/images/*","/fonts/**","/**/*.png","/**/*.jpg").permitAll() 22 .antMatchers("/","/index.html").permitAll() 23 .antMatchers("/report").hasRole("USER") 24 .and() 25 .csrf().ignoringAntMatchers("/druid/*"); 26
27
28 /*
29 * 開啟自動配置的登陸功能,效果,如果沒有登陸,沒有權限就會來到登陸頁面 30 * 1、login來到登陸頁 31 * 2、重定向到/login?error表示登陸失敗 32 * 3、更多詳細規定 33 * 4、默認post形式的 /login代表處理登陸 34 * 5、一但定制loginPage;那么 loginPage的post請求就是登陸 35 */
36 http.formLogin().usernameParameter("username").passwordParameter("password") 37 .loginPage("/login"); 38
39
40 /*
41 * 開啟自動配置的注銷功能 42 * 1、訪問 /logout 表示用戶注銷,清空session 43 * 注銷成功會返回 /login?logout 頁面; 44 * 注銷成功以后來到首頁 45 */
46 http.logout().logoutSuccessUrl("/"); 47
48
49 /*
50 * 開啟記住我功能 51 * 登陸成功以后,將cookie發給瀏覽器保存,以后訪問頁面帶上這個cookie,只要通過檢查就可以免登錄 52 * 點擊注銷會刪除cookie 53 */
54 http.rememberMe().rememberMeParameter("remember");
57 } 58
59 @Bean 60 UserDetailsService customUserDetailService() { // 注冊UserDetailsService 的bean 61 return new CustomUserDetailService(); 62 }
63
64 /**
65 * 認證信息管理 66 * spring5中摒棄了原有的密碼存儲格式,官方把spring security的密碼存儲格式改了 67 * 68 */
69 @Autowired 70 public void configure(AuthenticationManagerBuilder auth) throws Exception { 71 auth.userDetailsService(customUserDetailService()) //認證信息存儲(自定義)
72 .passwordEncoder(passwordEncoder()); 73 //
74 // auth.inMemoryAuthentication() //認證信息存儲到內存中 75 // .passwordEncoder(passwordEncoder()) 76 // .withUser("user").password(passwordEncoder().encode("123")).roles("USER");
77
78 } 79
80 private PasswordEncoder passwordEncoder() { 81 return new BCryptPasswordEncoder(); 82 } 83
84 }
3、自定義用戶驗證類實現UserDetailsService接口,進行授權驗證
1 @Service 2 public class CustomUserDetailService implements UserDetailsService { 3
4 @Autowired 5 private UserService userService; 6
7 @Autowired 8 HttpServletRequest request; 9
10 @Override 11 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 12 HttpSession session = request.getSession(); 13 User user = userService.getUserByUsername(username); 14 if(user==null){ 15 session.setAttribute("loginMsg","用戶名"+username+"不存在"); 16 throw new UsernameNotFoundException("用戶名"+username+"不存在"); 17 } 18 List<SimpleGrantedAuthority> authorities = new ArrayList<>(); 19 authorities.add(new SimpleGrantedAuthority("USER")); 20 return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),authorities); 21 } 22 }
二、進行用戶密碼驗證(AbstractUserDetailsAuthenticationProvider)
第一種方法雖然也能認證授權,但是問題顯而易見,沒有進行密碼驗證,主要用戶名對了 就給權限 這很危險
流程跟一基本一樣
1、導入依賴
2、配置安全認證類,需要報紅色的地方修改一下
1 @Bean 2 AbstractUserDetailsAuthenticationProvider customAuthenticationProvide() { // 注冊AbstractUserDetailsAuthenticationProvider的bean
3 return new CustomAuthenticationProvider(); 4 } 5
6 @Autowired 7 public void configure(AuthenticationManagerBuilder auth) throws Exception { 8 auth.authenticationProvider(customAuthenticationProvide()); //認證信息存儲(自定義) 9 //
10 // auth.inMemoryAuthentication() //認證信息存儲到內存中 11 // .passwordEncoder(passwordEncoder()) 12 // .withUser("user").password(passwordEncoder().encode("123")).roles("USER");
13
14 }
3、自定義用戶驗證類實現AbstractUserDetailsAuthenticationProvider類,進行授權驗證
1 import org.springframework.beans.factory.annotation.Autowired; 2 import org.springframework.security.authentication.BadCredentialsException; 3 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 4 import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider; 5 import org.springframework.security.core.AuthenticationException; 6 import org.springframework.security.core.authority.SimpleGrantedAuthority; 7 import org.springframework.security.core.userdetails.UserDetails; 8 import org.springframework.security.core.userdetails.UsernameNotFoundException; 9 import org.springframework.stereotype.Service; 10 import top.xiaoyl.entities.User; 11
12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpSession; 14 import java.util.ArrayList; 15 import java.util.List; 16
17 @Service 18 public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { 19
20 @Autowired 21 private UserService userService; 22
23 @Autowired 24 private HttpServletRequest request; 25
26 @Override 27 protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { 28
29 } 30
31 @Override 32 protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { 33 System.out.println("retrieveUser"); 34 HttpSession session = request.getSession(); 35 if(username==null || username.length()==0){ 36 session.setAttribute("loginMsg","用戶名不能為空"); 37 throw new UsernameNotFoundException("用戶名不能為空"); 38 } 39 User user = userService.getUserByUsername(username); 40 if(user==null){ 41 session.setAttribute("loginMsg","用戶名"+username+"不存在"); 42 throw new UsernameNotFoundException("用戶名"+username+"不存在"); 43 } 44 if(!authentication.getCredentials().toString().equals(user.getPassword())){ 45 session.setAttribute("loginMsg","密碼不正確"); 46 throw new BadCredentialsException("密碼不正確"); 47 } 48 List<SimpleGrantedAuthority> authorities = new ArrayList<>(); 49 authorities.add(new SimpleGrantedAuthority("USER")); 50 return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),authorities); 51 } 52 }