⒈自定義登陸頁面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 }