SpringSecurity個性化用戶認證流程

⒈自定義登陸頁面html

 1 package cn.coreqi.security.config;
 2 
 3 import org.springframework.context.annotation.Bean;
 4 import org.springframework.context.annotation.Configuration;
 5 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 6 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 7 import org.springframework.security.crypto.password.NoOpPasswordEncoder;
 8 import org.springframework.security.crypto.password.PasswordEncoder;
 9 
10 @Configuration
11 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
12     
13     @Bean
14     public PasswordEncoder passwordEncoder(){
15         return NoOpPasswordEncoder.getInstance();
16     }
17 
18     @Override
19     protected void configure(HttpSecurity http) throws Exception {
20         //http.httpBasic()    //httpBasic登陸 BasicAuthenticationFilter
21         http.formLogin()    //表單登陸 UsernamePasswordAuthenticationFilter
22                 //.loginPage("/coreqi-signIn.html")  //指定登陸頁面
23                 .loginPage("/authentication/require")
24                 .loginProcessingUrl("/authentication/form") //指定表單提交的地址用於替換UsernamePasswordAuthenticationFilter默認的提交地址
25                 .and()
26                 .authorizeRequests()    //對受權請求進行配置
27                 .antMatchers("/coreqi-signIn.html").permitAll() //指定登陸頁面不須要身份認證
28                 .anyRequest().authenticated()  //任何請求都須要身份認證
29                 .and().csrf().disable();    //禁用CSRF
30             //FilterSecurityInterceptor 整個SpringSecurity過濾器鏈的最後一環
31     }
32 }

 

 1 package cn.coreqi.security.controller;
 2 
 3 import cn.coreqi.security.support.SimpleResponse;
 4 import org.slf4j.Logger;
 5 import org.slf4j.LoggerFactory;
 6 import org.springframework.http.HttpStatus;
 7 import org.springframework.security.web.DefaultRedirectStrategy;
 8 import org.springframework.security.web.RedirectStrategy;
 9 import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
10 import org.springframework.security.web.savedrequest.RequestCache;
11 import org.springframework.security.web.savedrequest.SavedRequest;
12 import org.springframework.util.StringUtils;
13 import org.springframework.web.bind.annotation.GetMapping;
14 import org.springframework.web.bind.annotation.ResponseStatus;
15 import org.springframework.web.bind.annotation.RestController;
16 
17 import javax.servlet.http.HttpServletRequest;
18 import javax.servlet.http.HttpServletResponse;
19 import java.io.IOException;
20 
21 @RestController
22 public class SecurityController {
23 
24     private Logger logger = LoggerFactory.getLogger(getClass());
25 
26     //拿到引起跳轉的請求
27     private RequestCache requestCache = new HttpSessionRequestCache();  //SpringSecurity執行身份認證跳轉以前會將當前的請求緩存到HttpSessionRequestCache中
28     //咱們能夠經過HttpSessionRequestCache把以前緩存的請求拿出來。
29 
30     private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();  //Spring用於跳轉的工具
31 
32     /**
33      * 當須要身份認證時,跳轉到這裏
34      * @param request
35      * @param response
36      * @return
37      */
38     @GetMapping("/authentication/require")
39     @ResponseStatus(code = HttpStatus.UNAUTHORIZED) //返回401狀態碼
40     public SimpleResponse requireAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
41         SavedRequest savedRequest = requestCache.getRequest(request,response);  //SavedRequest就是跳轉前的請求
42         if(savedRequest != null){   //若是請求緩存存在的話
43             String target = savedRequest.getRedirectUrl();  //拿到引起跳轉的請求URL
44             logger.info("引起跳轉的請求URL是:" + target);
45             if(StringUtils.endsWithIgnoreCase(target,".html")){ //引起跳轉的請求URL是否以html結尾
46                 redirectStrategy.sendRedirect(request,response,"/coreqi-signIn.html"); //將請求跳轉到指定的Url
47             }
48         }
49         return new SimpleResponse(401,"訪問的服務須要身份認證,請引導用戶到登錄頁面",null);
50     }
51 }

 

⒉自定義登陸成功處理java

  默認狀況下SpringSecurity登陸成功了將會跳轉到以前引起登陸的那個請求上去,若是咱們須要自定義登陸成功後的處理過程,只須要實現AuthenticationSuccessHandler接口。(SpringSecurity默認的成功處理器是SavedRequestAwareAuthenticationSuccessHandler)web

 1 package cn.coreqi.security.authentication;
 2 
 3 import com.fasterxml.jackson.databind.ObjectMapper;
 4 import org.slf4j.Logger;
 5 import org.slf4j.LoggerFactory;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.security.core.Authentication;
 8 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
 9 import org.springframework.stereotype.Component;
10 
11 import javax.servlet.ServletException;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 import java.io.IOException;
15 
16 @Component("coreqiAuthenticationSuccessHandler")
17 public class CoreqiAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
18 
19     private Logger logger = LoggerFactory.getLogger(getClass());
20 
21     @Autowired
22     private ObjectMapper objectMapper;  //將對象轉換爲Json的工具類,SpringMVC在啓動的時候會自動爲咱們註冊ObjectMapper
23     /**
24      *
25      * @param httpServletRequest    不知道
26      * @param httpServletResponse   不知道
27      * @param authentication   Authentication接口是SpringSecurity的一個核心接口,它的做用是封裝咱們的認證信息,包含認證請求中的一些信息,包括認證請求的ip,Session是什麼,以及認證用戶的信息等等。
28      * @throws IOException
29      * @throws ServletException
30      */
31     @Override
32     public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
33         logger.info("登陸成功");
34 
35         httpServletResponse.setContentType("application/json;charset=UTF-8");
36         httpServletResponse.getWriter().write(objectMapper.writeValueAsString(authentication));
37     }
38 }

配置spring

 1 package cn.coreqi.security.config;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.context.annotation.Bean;
 5 import org.springframework.context.annotation.Configuration;
 6 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 8 import org.springframework.security.crypto.password.NoOpPasswordEncoder;
 9 import org.springframework.security.crypto.password.PasswordEncoder;
10 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
11 
12 @Configuration
13 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
14 
15     @Autowired
16     private AuthenticationSuccessHandler coreqiAuthenticationSuccessHandler;
17 
18     @Bean
19     public PasswordEncoder passwordEncoder(){
20         return NoOpPasswordEncoder.getInstance();
21     }
22 
23     @Override
24     protected void configure(HttpSecurity http) throws Exception {
25         //http.httpBasic()    //httpBasic登陸 BasicAuthenticationFilter
26         http.formLogin()    //表單登陸 UsernamePasswordAuthenticationFilter
27                 //.loginPage("/coreqi-signIn.html")  //指定登陸頁面
28                 .loginPage("/authentication/require")
29                 .loginProcessingUrl("/authentication/form") //指定表單提交的地址用於替換UsernamePasswordAuthenticationFilter默認的提交地址
30                 .successHandler(coreqiAuthenticationSuccessHandler) //登陸成功之後要用咱們自定義的登陸成功處理器,不用Spring默認的。
31                 .and()
32                 .authorizeRequests()    //對受權請求進行配置
33                 .antMatchers("/coreqi-signIn.html").permitAll() //指定登陸頁面不須要身份認證
34                 .anyRequest().authenticated()  //任何請求都須要身份認證
35                 .and().csrf().disable();    //禁用CSRF
36             //FilterSecurityInterceptor 整個SpringSecurity過濾器鏈的最後一環
37     }
38 }

 

⒊自定義登陸失敗處理json

只須要實現AuthenticationSuccessHandler接口便可。(默認爲SimpleUrlAuthenticationFailureHandler)緩存

 1 package cn.coreqi.security.authentication;
 2 
 3 import com.fasterxml.jackson.databind.ObjectMapper;
 4 import org.slf4j.Logger;
 5 import org.slf4j.LoggerFactory;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.http.HttpStatus;
 8 import org.springframework.security.core.AuthenticationException;
 9 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
10 import org.springframework.stereotype.Component;
11 
12 import javax.servlet.ServletException;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15 import java.io.IOException;
16 
17 @Component("coreqiAuthenticationFailureHandler")
18 public class CoreqiAuthenticationFailureHandler implements AuthenticationFailureHandler {
19 
20     private Logger logger = LoggerFactory.getLogger(getClass());
21 
22     @Autowired
23     private ObjectMapper objectMapper;  //將對象轉換爲Json的工具類,SpringMVC在啓動的時候會自動爲咱們註冊ObjectMapper
24 
25     /**
26      *
27      * @param httpServletRequest    不知道
28      * @param httpServletResponse   不知道
29      * @param e AuthenticationException對象包含了在認證過程當中發生的錯誤產生的異常
30      * @throws IOException
31      * @throws ServletException
32      */
33     @Override
34     public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
35         logger.info("登陸失敗");
36 
37 
38         httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());    //500狀態碼
39         httpServletResponse.setContentType("application/json;charset=UTF-8");
40         httpServletResponse.getWriter().write(objectMapper.writeValueAsString(e));
41     }
42 }

配置app

 1 package cn.coreqi.security.config;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.context.annotation.Bean;
 5 import org.springframework.context.annotation.Configuration;
 6 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 8 import org.springframework.security.crypto.password.NoOpPasswordEncoder;
 9 import org.springframework.security.crypto.password.PasswordEncoder;
10 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
11 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
12 
13 @Configuration
14 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
15 
16     @Autowired
17     private AuthenticationSuccessHandler coreqiAuthenticationSuccessHandler;
18 
19     @Autowired
20     private AuthenticationFailureHandler coreqiAuthenticationFailureHandler;
21 
22     @Bean
23     public PasswordEncoder passwordEncoder(){
24         return NoOpPasswordEncoder.getInstance();
25     }
26 
27     @Override
28     protected void configure(HttpSecurity http) throws Exception {
29         //http.httpBasic()    //httpBasic登陸 BasicAuthenticationFilter
30         http.formLogin()    //表單登陸 UsernamePasswordAuthenticationFilter
31                 //.loginPage("/coreqi-signIn.html")  //指定登陸頁面
32                 .loginPage("/authentication/require")
33                 .loginProcessingUrl("/authentication/form") //指定表單提交的地址用於替換UsernamePasswordAuthenticationFilter默認的提交地址
34                 .successHandler(coreqiAuthenticationSuccessHandler) //登陸成功之後要用咱們自定義的登陸成功處理器,不用Spring默認的。
35                 .failureHandler(coreqiAuthenticationFailureHandler) //本身體會把
36                 .and()
37                 .authorizeRequests()    //對受權請求進行配置
38                 .antMatchers("/coreqi-signIn.html").permitAll() //指定登陸頁面不須要身份認證
39                 .anyRequest().authenticated()  //任何請求都須要身份認證
40                 .and().csrf().disable();    //禁用CSRF
41             //FilterSecurityInterceptor 整個SpringSecurity過濾器鏈的最後一環
42     }
43 }
相關文章
相關標籤/搜索