1.自定義響應結構
/** * 自定義響應結構 */ @Data public class Result { // 響應業務狀態 private Integer code; // 響應消息 private String message; // 響應中的數據 private Object data; public Result() { } public Result(Object data) { this.code = 200; this.message = "OK"; this.data = data; } public Result(String message, Object data) { this.code = 200; this.message = message; this.data = data; } public Result(Integer code, String message, Object data) { this.code = code; this.message = message; this.data = data; } public static Result ok() { return new Result(null); } public static Result ok(String message) { return new Result(message, null); } public static Result ok(Object data) { return new Result(data); } public static Result ok(String message, Object data) { return new Result(message, data); } public static Result build(Integer code, String message) { return new Result(code, message, null); } public static Result build(Integer code, String message, Object data) { return new Result(code, message, data); } public String toJsonString() { return JSON.toJSONString(this); } /** * JSON字符串轉成 Result 對象 * @param json * @return */ public static Result format(String json) { try { return JSON.parseObject(json, Result.class); } catch (Exception e) { e.printStackTrace(); } return null; } }
2.創建CustomAuthenticationSuccessHandler 實現 CustomAuthenticationSuccessHandler 接口,認證成功處理器:通過Ajax 請求響應一個JSON數據,前端接收到響應的數據進行跳轉。可以使用自定義登錄成功處理邏輯。
/** * 自定義的認證成功處理器 * 1.決定響應json還是跳轉頁面,或者認證成功進行其他處理 */ @Component("customAuthenticationSuccessHandler") public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { //認證成功后響應json數據給前端 Result result = Result.ok("認證成功"); String s = result.toJsonString(); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(s); } }
3..創建CustomAuthenticationFailureHandler實現 AuthenticationFailureHandler接口,認證失敗處理器:比如登錄錯誤后記錄日志,當次數超過3次后,2小時內不允許登錄,那可以使用自定義登錄失敗后,進行邏輯處理
/** * 自定義認證失敗處理器 */ @Component("customAuthenticationFailureHandler") public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { //認證失敗后響應json數據給前端 Result result = Result.build(HttpStatus.UNAUTHORIZED.value(), exception.getMessage()); String s = result.toJsonString(); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(s); } }
4.在安全配置類SpringSecurityConfifig 中注入 和 引用自定義認證成功和失敗處理器 CustomAuthenticationSuccessHandler、CustomAuthenticationFailureHandler
@Autowired CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler; @Autowired CustomAuthenticationFailureHandler customAuthenticationFailureHandler; /** * 資源權限配置(過濾器鏈): * 1、被攔截的資源 * 2、資源所對應的角色權限 * 3、定義認證方式:httpBasic 、httpForm * 4、定制登錄頁面、登錄請求地址、錯誤處理方式 * 5、自定義 spring security 過濾器 * * @param http * @throws Exception */ @Override protected void configure(HttpSecurity http) throws Exception { //http.httpBasic()//采用httpBasic 認證方式 /*http.formLogin() .loginPage("/login/page")// 交給 /login/page 響應認證(登錄)頁面 .loginProcessingUrl("/login/form") // 登錄表單提交處理Url, 默認是 /login .usernameParameter("name") // 默認用戶名的屬性名是 username .passwordParameter("pwd") // 默認密碼的屬性名是 password .and() .authorizeRequests()//認證請求 .antMatchers("/login/page").permitAll()//自定義登錄頁不需要認證 .anyRequest().authenticated();// 所有進入應用的HTTP請求都要進行認證*/ http.formLogin() .loginPage(securityProperties.getLoginPage())// 交給 /login/page 響應認證(登錄)頁面 .loginProcessingUrl(securityProperties.getLoginProcessingUrl()) // 登錄表單提交處理Url, 默認是 /login .usernameParameter(securityProperties.getUsernameParameter()) // 默認用戶名的屬性名是 username .passwordParameter(securityProperties.getPasswordParameter()) // 默認密碼的屬性名是 password .successHandler(customAuthenticationSuccessHandler)//自定義認證成功處理器 .failureHandler(customAuthenticationFailureHandler)//自定義認證失敗處理器 .and() .authorizeRequests()//認證請求 .antMatchers(securityProperties.getLoginPage()).permitAll()//自定義登錄頁不需要認證 .anyRequest().authenticated();// 所有進入應用的HTTP請求都要進行認證 }
完整代碼地址:https://gitee.com/zhechaochao/security-parent.git
