【SpringSecurity】四、登录处理器

文章目录

  • 1、登录成功处理器
  • 2、登录失败处理器
  • 3、无权限处理器
  • 4、登出(退出)处理器
  • 5、安全配置类WebSecurityConfig

前后端分离背景下,前后端通过json进行交互,登录成功或失败,返回的不是一个html页面,而是一个json串。

1、登录成功处理器

先定义个统一结果返回类:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class HttpResult {
    private Integer code;
    private String msg;
    private Object data;
    public HttpResult(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

定义登录成功处理器,登录成功时,调用它里面的方法:

@Component
public class MyAutheticationSuccessHandle implements AuthenticationSuccessHandler {
@Resource
    private ObjectMapper objectMapper;  //注入它方便进行对象的序列化和反序列化

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    	//实体类加了@Builder注解,这里换种方式创建对象
    	HttpResult httpResult = HttpResult.builder()
		    	.code(200)
		    	.msg("登录成功")
		    	.build();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        String responseJson = objectMapper.writeValueAsString(httpResult);
        response.getWriter().write(responseJson);
        response.getWriter().flush();
    }
}

在Web安全管理适配器这里,改成表单页登录成功后,走登录成功处理器:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Resource
	MyAutheticationSuccessHandle myAutheticationSuccessHandle;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //任何访问均需要认证
        http.authorizeRequests().anyRequest().authenticated();
        //登录放行,走登录成功处理器
        http.formLogin().successHandler(myAutheticationSuccessHandle).permitAll();
    }
}


返回成功:

【SpringSecurity】四、登录处理器_第1张图片

2、登录失败处理器

/**
 * 登陆失败的处理器
 */
@Component
public class AppAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Resource
    private ObjectMapper objectMapper;


    /**
     * @param request 当前的请求对象
     * @param response 当前的响应对象
     * @param exception 失败的原因的异常
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        //设置响应编码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        //返回JSON出去
        HttpResult result=new HttpResult(-1,"登陆失败");
        if(exception instanceof BadCredentialsException){
            result.setData("密码不正确");
        }else if(exception instanceof DisabledException){
            result.setData("账号被禁用");
        }else if(exception instanceof UsernameNotFoundException){
            result.setData("用户名不存在");
        }else if(exception instanceof CredentialsExpiredException){
            result.setData("密码已过期");
        }else if(exception instanceof AccountExpiredException){
            result.setData("账号已过期");
        }else if(exception instanceof LockedException){
            result.setData("账号被锁定");
        }else{
            result.setData("未知异常");
        }
        //把result转成JSON
        String json = objectMapper.writeValueAsString(result);
        //响应出去
        PrintWriter out = response.getWriter();
        out.write(json);
        out.flush();
    }
}

关于AuthenticationException异常的继承关系:Ctrl+H

【SpringSecurity】四、登录处理器_第2张图片

3、无权限处理器

/**
 * 无权限的处理器
 */
@Component
public class AppAccessDeniedHandler implements AccessDeniedHandler {

	@Resource
    private ObjectMapper objectMapper;

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        //设置响应编码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        //返回JSON出去
        HttpResult result=new HttpResult(403,"无权限访问");
        //把result转成JSON
        String json = objectMapper.writeValueAsString(result);
        //响应出去
        PrintWriter out = response.getWriter();
        out.write(json);
        out.flush();
    }
}

4、登出(退出)处理器

/**
 * 退出成功的处理器
 */
@Component
public class AppLogoutSuccessHandler implements LogoutSuccessHandler {

	@Resource
    private ObjectMapper objectMapper;

    /**
     *
     * @param request
     * @param response
     * @param authentication 当前退出的用户对象
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //设置响应编码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        //返回JSON出去
        HttpResult result=new HttpResult(200,"退出成功");
        //把result转成JSON
        String json = objectMapper.writeValueAsString(result);
        //响应出去
        PrintWriter out = response.getWriter();
        out.write(json);
        out.flush();
    }
}

5、安全配置类WebSecurityConfig

最后修改下安全配置类,把上面定义的处理器加进来,完成逻辑闭环:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    // 注入登陆成功的处理器
    @Autowired
    private MyAutheticationSuccessHandle successHandler;

    // 注入登陆失败的处理器
    @Autowired
    private AppAuthenticationFailureHandler failureHandler;

    // 注入没有权限的处理器
    @Autowired
    private AppAccessDeniedHandler accessDeniedHandler;

    //  注入退出成功的处理器
    @Autowired
    private AppLogoutSuccessHandler logoutSuccessHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling()
        	.accessDeniedHandler(accessDeniedHandler);
        http.formLogin()
        	.successHandler(successHandler)
        	.failureHandler(failureHandler)
        	.permitAll();
        http.logout()
        	.logoutSuccessHandler(logoutSuccessHandler);
        	
        http.authorizeRequests()
        	.mvcMatchers("/teacher/**")
        	.hasRole("teacher")
        	.anyRequest()
        	.authenticated();
    }
}

重启服务后,访问没权限的资源:

【SpringSecurity】四、登录处理器_第3张图片

你可能感兴趣的:(SpringSecurity,SpringSecurity,Spring)