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


自定义一个处理登录逻辑并返回经过认证的用户信息,通过重写方法实现向r传入时使用处理认证
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {private UserDetailsService userDetailsService;@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {SmsCodeAuthenticationToken smsCodeAuthenticationToken = (SmsCodeAuthenticationToken) authentication;UserDetails user = userDetailsService.loadUserByUsername((String)smsCodeAuthenticationToken.getPrincipal());if(user == null){throw new InternalAuthenticationServiceException("用户不存在");}SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(user,user.getAuthorities());authenticationResult.setDetails(smsCodeAuthenticationToken.getDetails());return authenticationResult;}@Overridepublic boolean supports(Class aClass) {return SmsCodeAuthenticationToken.class.isAssignableFrom(aClass);}public UserDetailsService getUserDetailsService() {return userDetailsService;}public void setUserDetailsService(UserDetailsService userDetailsService) {this.userDetailsService = userDetailsService;}}
中含有一个是用来查找用户的,在这只是模拟过程没有真实的进行数据库查找
@Componentpublic class MyUserDetailService implements UserDetailsService {@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {/*** 这里实际情况应该是根据参数s查询数据库用户数据*/return new User(s,"123", AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));}}
把各个组件拼装起来并且把加入到 的过滤器链
@Componentpublic class SmsCodeAuthenticationSecurityConfig extends SecurityConfigurerAdapter {@Autowiredprivate AuthenticationSuccessHandler imoocAuthenticationSuccessHandler;@Autowiredprivate AuthenticationFailureHandler imoocAuthenticationFailureHandler;@Autowiredprivate UserDetailsService myUserDetailsService;@Overridepublic void configure(HttpSecurity builder) throws Exception {SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter();smsCodeAuthenticationFilter.setAuthenticationManager(builder.getSharedObject(AuthenticationManager.class));//配置smsCodeAuthenticationFilter成功和失败的处理器smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(imoocAuthenticationSuccessHandler);smsCodeAuthenticationFilter.setAuthenticationFailureHandler(imoocAuthenticationFailureHandler);//设置SmsCodeAuthenticationProvider的UserDetailsServiceSmsCodeAuthenticationProvider smsCodeAuthenticationProvider = new SmsCodeAuthenticationProvider();smsCodeAuthenticationProvider.setUserDetailsService(myUserDetailsService);//把smsCodeAuthenticationFilter过滤器添加在UsernamePasswordAuthenticationFilter之前builder.authenticationProvider(smsCodeAuthenticationProvider);builder.addFilterBefore(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);}}
代码中认证是啊比处理器在上文中已经有提到,这里还有一个认证成功处理器,这个认证成功的处理方式就是把认证成功的认证信息在返回中打印出来
@Componentpublic class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {private Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);@Autowiredprivate ObjectMapper objectMapper;@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {logger.info("登录成功");response.setContentType("application/json;charset=UTF-8");response.getWriter().write(objectMapper.writeValueAsString(authentication));}}
配置和测试

Spring Security实现短信验证码登录

文章插图
配置中把加到之前,把上一步配置加入 。使用自定义登录界面,并且把登录界面和获取验证码的接口都暴漏出来