Spring Security实现短信验证码登录( 二 )


其中抛出一个校验异常
public class ValidateCodeException extends AuthenticationException {private static final long serialVersionUID = -7285211528095468156L;public ValidateCodeException(String msg) {super(msg);}}
还有一个认证失败的,失败处理是在返回中打印错误信息返回体,就是一个简单的服务器返回体
@Componentpublic class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {private Logger logger = LoggerFactory.getLogger(getClass());@Autowiredprivate ObjectMapper objectMapper;@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {logger.info("登录失败");response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());response.setContentType("application/json;charset=UTF-8");response.getWriter().write(objectMapper.writeValueAsString(new SimpleResponse(exception.getLocalizedMessage())));}}
public class SimpleResponse {private Object content;public SimpleResponse(Object content) {this.content = content;}public Object getContent() {return content;}public void setContent(Object content) {this.content = content;}}
参照 表单登录的流程自定义一套手机验证码的登录流程
有看过 源码的同学应该知道表单登录的实现流程,大致如下:
在这进行手机验证码的登录,参照表单登录流程,咋们来实现一个一样的手机验证码登录流程
参考、源码,实现自定义和
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter{public static final String SPRING_SECURITY_FORM_MOBILE = "mobile";private String mobileParameter = SPRING_SECURITY_FORM_MOBILE;private boolean postOnly = true;public SmsCodeAuthenticationFilter() {super(new AntPathRequestMatcher("/authentication/mobile", "POST"));}@Overridepublic Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse response) throws AuthenticationException {if (postOnly && !request.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());}String mobile = obtainMobile(request);if (mobile == null) {mobile = "";}mobile = mobile.trim();SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile);// Allow subclasses to set the "details" propertysetDetails(request, authRequest);return this.getAuthenticationManager().authenticate(authRequest);}/*** 获取手机号* @param request* @return*/protected String obtainMobile(HttpServletRequest request) {return request.getParameter(mobileParameter);}protected void setDetails(HttpServletRequest request,SmsCodeAuthenticationToken authRequest) {authRequest.setDetails(authenticationDetailsSource.buildDetails(request));}public void setUsernameParameter(String mobileParameter) {Assert.hasText(mobileParameter, "mobile parameter must not be empty or null");this.mobileParameter = mobileParameter;}public void setPostOnly(boolean postOnly) {this.postOnly = postOnly;}public String getMobileParameter() {return mobileParameter;}}
public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;private final Object principal;public SmsCodeAuthenticationToken(String mobile) {super(null);this.principal = mobile;setAuthenticated(false);}public SmsCodeAuthenticationToken(Object principal,Collection authorities) {super(authorities);this.principal = principal;super.setAuthenticated(true); // must use super, as we override}public Object getCredentials() {return null;}public Object getPrincipal() {return this.principal;}public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {if (isAuthenticated) {throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");}super.setAuthenticated(false);}@Overridepublic void eraseCredentials() {super.eraseCredentials();}}