You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
3.6 KiB
80 lines
3.6 KiB
package cc.bnblogs.springsecurity.validate.imagecode; |
|
|
|
import cc.bnblogs.springsecurity.Exception.ValidateCodeException; |
|
import cc.bnblogs.springsecurity.controller.ValidateCodeController; |
|
import org.apache.commons.lang3.StringUtils; |
|
import org.springframework.beans.factory.annotation.Autowired; |
|
import org.springframework.security.web.authentication.AuthenticationFailureHandler; |
|
import org.springframework.social.connect.web.HttpSessionSessionStrategy; |
|
import org.springframework.social.connect.web.SessionStrategy; |
|
import org.springframework.stereotype.Component; |
|
import org.springframework.web.bind.ServletRequestBindingException; |
|
import org.springframework.web.bind.ServletRequestUtils; |
|
import org.springframework.web.context.request.ServletWebRequest; |
|
import org.springframework.web.filter.OncePerRequestFilter; |
|
|
|
import javax.servlet.FilterChain; |
|
import javax.servlet.ServletException; |
|
import javax.servlet.http.HttpServletRequest; |
|
import javax.servlet.http.HttpServletResponse; |
|
import java.io.IOException; |
|
|
|
/** |
|
* 本过滤器只会校验一次 |
|
*/ |
|
@Component |
|
public class ValidateCodeFilter extends OncePerRequestFilter { |
|
|
|
@Autowired |
|
private AuthenticationFailureHandler authenticationFailureHandler; |
|
|
|
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); |
|
|
|
@Override |
|
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, |
|
FilterChain filterChain) throws ServletException, IOException { |
|
// 判断请求的路径和方法决定是否进行验证码校验 |
|
if (StringUtils.equalsIgnoreCase("/login", httpServletRequest.getRequestURI()) |
|
&& StringUtils.equalsIgnoreCase(httpServletRequest.getMethod(), "post")) { |
|
try { |
|
validateCode(new ServletWebRequest(httpServletRequest)); |
|
} catch (ValidateCodeException e) { |
|
// 校验失败,返回对应错误信息 |
|
authenticationFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, e); |
|
return; |
|
} |
|
} |
|
// 不需要进行验证码校验,进入下一步 |
|
filterChain.doFilter(httpServletRequest, httpServletResponse); |
|
} |
|
|
|
/** |
|
* 验证码校验 |
|
* @param servletWebRequest |
|
* @throws ServletRequestBindingException |
|
*/ |
|
private void validateCode(ServletWebRequest servletWebRequest) throws ServletRequestBindingException { |
|
// 从Session中取出ImageCode对象 |
|
ImageCode codeInSession = (ImageCode) sessionStrategy.getAttribute(servletWebRequest, |
|
ValidateCodeController.SESSION_KEY_IMAGE_CODE); |
|
// 获取用户输入的验证码 |
|
String codeInRequest = ServletRequestUtils.getStringParameter(servletWebRequest. |
|
getRequest(), "imageCode"); |
|
|
|
if (StringUtils.isBlank(codeInRequest)) { |
|
throw new ValidateCodeException("验证码不能为空!"); |
|
} |
|
if (codeInSession == null) { |
|
throw new ValidateCodeException("验证码不存在!"); |
|
} |
|
if (codeInSession.isExpire()) { |
|
sessionStrategy.removeAttribute(servletWebRequest, ValidateCodeController.SESSION_KEY_IMAGE_CODE); |
|
throw new ValidateCodeException("验证码已过期!"); |
|
} |
|
if (!StringUtils.equalsIgnoreCase(codeInSession.getCode(), codeInRequest)) { |
|
throw new ValidateCodeException("验证码不正确!"); |
|
} |
|
// 从Session中移除验证码对象 |
|
sessionStrategy.removeAttribute(servletWebRequest, ValidateCodeController.SESSION_KEY_IMAGE_CODE); |
|
} |
|
} |