现在主流的登录方式主要有 3 种:账号密码登录、短信验证码登录和第三方授权登录,前面一节Spring security(三)---认证过程已分析了spring security账号密码方式登陆,现在我们来分析一下spring security短信方式认证登陆。
Spring security 短信方式、IP验证等类似模式登录方式验证,可以根据账号密码方式登录步骤仿写出来,其主要以以下步骤进行展开:
-
-
自定义Authentication
-
自定义AuthenticationProvider
-
自定义UserDetailsService
-
SecurityConfig配置
1. 自定义filter:
自定义filter可以根据UsernamePasswordAuthenticationFilter过滤器进行仿写,其实质即实现AbstractAuthenticationProcessingFilter抽象类,主要流程分为:
-
构建构造器,并在构造器中进行配置请求路径以及请求方式的过滤
-
自定义attemptAuthentication()认证步骤
-
在2步骤中认证过程中需要AuthenticationProvider进行最终的认证,在认证filter都需要将AuthenticationProvider设置进filter中,而管理AuthenticationProvider的是AuthenticationManager,因此我们创建过滤器filter的时候需要设置AuthenticationManager,这步具体详情在5.1 SecurityConfig配置步骤。
在第2步中attemptAuthentication()认证方法主要进行以下步骤:
1).post请求认证;
2).request请求获取手机号码和验证码;
3).用自定义的Authentication对象封装手机号码和验证码;
4).使用AuthenticationManager.authenticate()方法进行验证。
自定义filter实现代码:
public class SmsAuthenticationfilter extends AbstractAuthenticationProcessingFilter { private boolean postOnly = true; public SmsAuthenticationfilter() { super(new AntPathRequestMatcher(SecurityConstants.APP_MOBILE_LOGIN_URL, "POST")); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { if (postOnly && !request.getMethod().equals("POST")) { throw new AuthenticationServiceException( "Authentication method not supported: " + request.getMethod()); } Assert.hasText(SecurityConstants.MOBILE_NUMBER_PARAMETER, "mobile parameter must not be empty or null"); String mobile = request.getParameter(SecurityConstants.MOBILE_NUMBER_PARAMETER);