private String processUrl;
private MyAuthenctiationFailureHandler myAuthenctiationFailureHandler;
public CaptchaAuthenticationFilter(String defaultFilterProcessesUrl,MyAuthenctiationFailureHandler myAuthenctiationFailureHandler) {
super(defaultFilterProcessesUrl);
this.processUrl = defaultFilterProcessesUrl;
this.myAuthenctiationFailureHandler = myAuthenctiationFailureHandler;
setAuthenticationFailureHandler(myAuthenctiationFailureHandler);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (processUrl.equals(req.getServletPath()) && “POST”.equalsIgnoreCase(req.getMethod())) {
Object expect = req.getSession().getAttribute(Oauth2Const.VERIFYCODE_SESSION_KEY);
String code = req.getParameter(“code”);
log.info("========expect: " + expect + " code:" + code);
try {
validImage(req, res, code, expect);
} catch (AuthenticationException e) {
myAuthenctiationFailureHandler.onAuthenticationFailure(req, res, e);
return;
}
}
chain.doFilter(request, response);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws AuthenticationException {
return null;
}
/**
-
@param
-
@param
-
@param code 获取的验证码参数
-
@param verCode session中保存的验证码
-
@throws IOException
-
@throws ServletException
*/
public void validImage(HttpServletRequest req, HttpServletResponse res, String code, Object verCode) {
String verCodeStr;
if (null == verCode) {
throw new InsufficientAuthenticationException(Oauth2Const.VERIFYCODE_FAILURE);
} else {
verCodeStr = verCode.toString();
}
LocalDateTime localDateTime = (LocalDateTime) req.getSession().getAttribute(“codeTime”);
long past = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
long now = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
if (verCodeStr == null || code == null || code.isEmpty() || !verCodeStr.equalsIgnoreCase(code)) {
throw new InsufficientAuthenticationException(Oauth2Const.VERIFYCODE_ERROR);
} else if ((now - past) / 1000 / 60 > 2) {//两分钟
throw new InsufficientAuthenticationException(Oauth2Const.VERIFYCODE_EXPIRED);
} else {
//验证成功,删除存储的验证码
req.getSession().removeAttribute(Oauth2Const.VERIFYCODE_SESSION_KEY);
}
}
}
}
processUrl是spring security拦截的请求地址,failureUrl是验证失败时的跳转地址。在生成验证码的时候,要将验证码存到session中。验证时从session中获取验证码,并将session中的验证码移除,否则可以重复登录(使用浏览器的重发功能)。
MyAuthenctiationFailureHandler :自定义登录失败处理器。
void validImage(HttpServletRequest req, HttpServletResponse res, String code, Object verCode)该方法是图片验证码验证方法。
unsuccessfulAuthentication(req, res, new InsufficientAuthenticationException(Oauth2Const.VERIFYCODE_ERROR)); 验证失败会执行MyAuthenctiationFailureHandler 中的 onAuthenticationFailu
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
re ()方法。
然后将自己的过滤器加到spring security的过滤器链中。如:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override