自定义图片验证码过滤器拦截路径
1.1配置文件
security.imageCodeUrl=/user,/user/*,/authentication/form
1.2核心代码
package org.xyssmysql.springsecurity.learn.browser.filter; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import org.springframework.web.filter.GenericFilterBean; import org.springframework.web.filter.OncePerRequestFilter; import org.xyssmysql.common.constant.SymbolConstant; import org.xyssmysql.common.core.exception.BusinessException; import org.xyssmysql.common.util.RequestUtil; import org.xyssmysql.springsecurity.learn.browser.controller.CommonAuthenticationFailureHandler; import org.xyssmysql.springsecurity.learn.browser.global.service.BrowserRedisService; import org.xyssmysql.springsecurity.learn.core.config.SecurityProperties; import org.xyssmysql.springsecurity.learn.core.exception.BaseAuthenticationException; /** * OncePerRequestFilter:该过滤器确保只校验一次 * @desc 自定义的图片验证码过滤器 * @author huangshiqing * @date */ @Component public class ImageCodeSecurityFilter extends OncePerRequestFilter implements InitializingBean{ @Autowired BrowserRedisService browserRedisService; @Autowired private CommonAuthenticationFailureHandler commonAuthenticationFailureHandler; public Set<String> urls=new HashSet<String>(); @Autowired private SecurityProperties securityProperties; /** * 路径匹配类 */ @Autowired private AntPathMatcher antPathMatcher;
//初始化bean之后的,属性注入 @Override public void afterPropertiesSet() throws ServletException { super.afterPropertiesSet(); String[] urlStrArray = StringUtils.splitByWholeSeparatorPreserveAllTokens(securityProperties.getImageCodeUrl(), SymbolConstant.comma); urls.addAll(Arrays.asList(urlStrArray)); } /** * 图片验证码过滤器核心方法 */ @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String requestMethod = request.getMethod(); String requestURI = request.getRequestURI(); boolean requireFilter=false; for (String url : urls) { if(antPathMatcher.match(url, requestURI)) { requireFilter=true; break; } } //不满足需要验证的条件("/authentication/form".equals(requestURI)&& StringUtils.endsWithIgnoreCase(requestMethod, "post")) if(requireFilter) { //1.获取该session下对应的图片验证码 String imageCodeCorrect = browserRedisService.getImageCode(RequestUtil.getSessionId(request)); //2.如果为空则直接响应需要重新获取验证码 if(StringUtils.isEmpty(imageCodeCorrect)) { BaseAuthenticationException baseAuthenticationException = new BaseAuthenticationException("验证码已过期!"); // throw BusinessException.error("验证码已过期!"); commonAuthenticationFailureHandler.onAuthenticationFailure(request, response, baseAuthenticationException); } //3.如果不一致响应验证码不一致 if(!imageCodeCorrect.equals(request.getParameter("imageCode"))) { BaseAuthenticationException baseAuthenticationException = new BaseAuthenticationException("验证码输入错误!"); commonAuthenticationFailureHandler.onAuthenticationFailure(request, response, baseAuthenticationException); } filterChain.doFilter(request, response); } //4.放行 else{ filterChain.doFilter(request, response); } } /*@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpServletRequest=(HttpServletRequest) request; HttpServletResponse httpServletResponse=(HttpServletResponse) response; String requestMethod = httpServletRequest.getMethod(); String requestURI = httpServletRequest.getRequestURI(); //不满足需要验证的条件 if(("/authentication/form".equals(requestURI)&& StringUtils.endsWithIgnoreCase(requestMethod, "post"))) { //1.获取该session下对应的图片验证码 String imageCodeCorrect = browserRedisService.getImageCode(RequestUtil.getSessionId((HttpServletRequest) request)); //2.如果为空则直接响应需要重新获取验证码 if(StringUtils.isEmpty(imageCodeCorrect)) { BaseAuthenticationException baseAuthenticationException = new BaseAuthenticationException("验证码已过期!"); // throw BusinessException.error("验证码已过期!"); commonAuthenticationFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, baseAuthenticationException); } //3.如果不一致响应验证码不一致 if(!imageCodeCorrect.equals(request.getParameter("imageCode"))) { BaseAuthenticationException baseAuthenticationException = new BaseAuthenticationException("验证码输入错误!"); commonAuthenticationFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, baseAuthenticationException); } chain.doFilter(request, response); } //4.放行 else{ chain.doFilter(request, response); } }*/ }