SpringSecurity-6-基于Filter实现图形验证码

笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述SpringSecurity-6-基于Filter实现图形验证码相关的知识,希望能为你提供帮助。
SpringSecurity-6-基于Filter实现图形验证码SpringSecurity中有多种方式实现图像验证码,使用自定义过滤器去处理验证码逻辑是最简单的方式,只要将过滤器添加到合适的位置,当登录的时候,对验证码进行校验,成功就放行,失败则抛出异常。
?图形验证流程? 流程图如下

SpringSecurity-6-基于Filter实现图形验证码

文章图片
< /div>


< div th:if="$param.error">
< span th:text="$session.SPRING_SECURITY_LAST_EXCEPTION.message" style="color:#ff0000"> 用户名或 密码错误< /span>
< /div>
< input type="submit" value="https://www.songbingjia.com/android/登陆">

< /form>

< /body>
< /html>
实现效果重新启动项目,得到的登录页面效果如下

??实现验证码校验过滤器??
  • 编写自己的过滤器??ImageCodeValidateFilter???,让其继承??OncePerRequestFilter??(可以保证每一次请求只使用一次该过滤器)
  • 添加@Component注解
  • 在??ImageCodeValidateFilter??过滤器中从seesion获取验证码文字与用户输入比对,比对通过执行其他过滤器链
  • 比对不通过,抛出SessionAuthenticationException异常,交给AuthenticationFailureHandler处理,提示信息通过自定义异常 ValidateCodeExcetipn 抛出
  • 最后将??ImageCodeValidateFilter??放在UsernamePasswordAuthenticationFilter表单过滤器之前执行
@Component
public class ImageCodeValidateFilter extends OncePerRequestFilter


@Autowired
private MyAuthenticationFailureHandler failureHandler;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException

// 必须是登录的post请求才能进行验证,其他的直接放行
if(StringUtils.equals("/login/form",request.getRequestURI())
& & StringUtils.equalsIgnoreCase(request.getMethod(),"post"))
try
//1.验证谜底与用户输入是否匹配
validate(request);
catch(AuthenticationException e)
//2.捕获步骤1中校验出现异常,交给失败处理类进行进行处理
failureHandler.onAuthenticationFailure(request,response,e);
return;


//通过校验,就放行
filterChain.doFilter(request,response);


private void validate(HttpServletRequest request) throws ServletRequestBindingException

String sessionCode = (String)request.getSession().getAttribute(CaptchaController.SESSION_KEY);
String inpuCode = request.getParameter("code");
if(StringUtils.isEmpty(inpuCode))
throw new SessionAuthenticationException("验证码不能为空");

if(!inpuCode.equalsIgnoreCase(sessionCode))
throw new ValidateCodeException("验证码不能为空");



??创建验证码异常类?? 在exception包下创建ValidateCodeException,继承AuthenticationException
?注?:?org.springframework.security.core.AuthenticationException?
import org.springframework.security.core.AuthenticationException;

public class ValidateCodeException extends AuthenticationException
public ValidateCodeException(String msg, Throwable cause)
super(msg, cause);


public ValidateCodeException(String msg)
super(msg);


  • 修改MyAuthenticationFailureHandler类
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler
privatestatic ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException
// 当认证失败后,响应 JSON 数据给前端
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(exception.getMessage()));


??重构? ?LearnSrpingSecurity??
  1. 将ImageCodeValidateFilter过滤器添加到UsernamePasswordAuthenticationFilter过滤器前面,需要在configure(HttpSecurity http)方法中进行修改
具体步骤:
  • 注入ImageCodeValidateFilter
@Autowired
private ImageCodeValidateFilter codeValidateFilter;

  • 把 ImageCodeValidateFilter 添加 UsernamePasswordAuthenticationFilter 实例前

http.csrf().disable()//禁用跨站csrf防御,后面的章节会专门讲解
.addFilterBefore(codeValidateFilter, UsernamePasswordAuthenticationFilter.class)

?测试?
  • 不输入验证码

  • 输入错误验证码

  • 输入正确验证码



如果您觉得本文不错,?欢迎关注,点赞,收藏支持?,您的关注是我坚持的动力!
原创不易,转载请注明出处,感谢支持!如果本文对您有用,欢迎转发分享!
【SpringSecurity-6-基于Filter实现图形验证码】


    推荐阅读