SpringSecurity(五): 自定义认证成功和失败处理器响应给前端json数据

2021-06-11 01:04

阅读:402

  
/**
 * 自定义响应结构
 */
@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请求都要进行认证
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


评论


亲,登录后才可以留言!