生活随笔
收集整理的這篇文章主要介紹了
security模仿密码登录实现短信验证码登录
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
security模仿密碼登錄實(shí)現(xiàn)短信驗(yàn)證碼登錄
模仿UsernamePasswordAuthenticationToken創(chuàng)建短信驗(yàn)證碼的token類SmsAuthenticationToken
public class SmsAuthenticationToken extends AbstractAuthenticationToken {private static final long serialVersionUID
= 531L;private final Object principal
;private Object credentials
;public SmsAuthenticationToken(Object principal
, Object credentials
) {super(null);this.principal
= principal
;this.credentials
= credentials
;this.setAuthenticated(false);}public SmsAuthenticationToken(Object principal
, Object credentials
, Collection<? extends GrantedAuthority> authorities
) {super(authorities
);this.principal
= principal
;this.credentials
= credentials
;this.setAuthenticated(true);}@Overridepublic Object getCredentials() {return credentials
;}@Overridepublic Object getPrincipal() {return principal
;}@Overridepublic void eraseCredentials() {super.eraseCredentials();this.credentials
= null;}
}
模仿UsernamePasswordAuthenticationFilter創(chuàng)建處理短信驗(yàn)證碼的過濾器
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";private String usernameParameter
= "username";private String passwordParameter
= "password";private boolean postOnly
= true;public UsernamePasswordAuthenticationFilter() {super(new AntPathRequestMatcher("/login", "POST"));}public Authentication attemptAuthentication(HttpServletRequest request
, HttpServletResponse response
) throws AuthenticationException {if (this.postOnly
&& !request
.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: " + request
.getMethod());} else {String username
= this.obtainUsername(request
);String password
= this.obtainPassword(request
);username
= username
.trim();UsernamePasswordAuthenticationToken authRequest
= new UsernamePasswordAuthenticationToken(username
, password
);this.setDetails(request
, authRequest
);return this.getAuthenticationManager().authenticate(authRequest
);}}@Nullableprotected String obtainPassword(HttpServletRequest request
) {return request
.getParameter(this.passwordParameter
);}@Nullableprotected String obtainUsername(HttpServletRequest request
) {return request
.getParameter(this.usernameParameter
);}protected void setDetails(HttpServletRequest request
, UsernamePasswordAuthenticationToken authRequest
) {authRequest
.setDetails(this.authenticationDetailsSource
.buildDetails(request
));}public void setUsernameParameter(String usernameParameter
) {Assert.hasText(usernameParameter
, "Username parameter must not be empty or null");this.usernameParameter
= usernameParameter
;}public void setPasswordParameter(String passwordParameter
) {Assert.hasText(passwordParameter
, "Password parameter must not be empty or null");this.passwordParameter
= passwordParameter
;}public void setPostOnly(boolean postOnly
) {this.postOnly
= postOnly
;}public final String getUsernameParameter() {return this.usernameParameter
;}public final String getPasswordParameter() {return this.passwordParameter
;}
}
模仿DaoAuthenticationProvider創(chuàng)建處理SmsAuthenticationToken的Provider
public class SmsAuthenticationProvider implements AuthenticationProvider {private SmsUserDetailsService userDetailsService
;@Overridepublic Authentication authenticate(Authentication authentication
) throws AuthenticationException {final SmsAuthenticationToken smsAuthenticationToken
= (SmsAuthenticationToken) authentication
;final String mobile
= smsAuthenticationToken
.getPrincipal() == null ? "" :smsAuthenticationToken
.getPrincipal().toString();final String code
= smsAuthenticationToken
.getCredentials().toString();if (code
== null) {throw new SmsAuthenticationException(SmsAuthenticationHandler.AuthenticationStatus.NO_VERIFY_CODE);}checkSmsCode(mobile
, code
);final UserDetails userDetails
= userDetailsService
.loadUserByUsername(mobile
);return createSuccessAuthenticationToken(smsAuthenticationToken
, userDetails
);}private SmsAuthenticationToken createSuccessAuthenticationToken(SmsAuthenticationToken smsAuthenticationToken
, UserDetails userDetails
) {final SmsAuthenticationToken authenticationToken
= new SmsAuthenticationToken(userDetails
, null, userDetails
.getAuthorities());authenticationToken
.setDetails(smsAuthenticationToken
.getDetails());return authenticationToken
;}public void setUserDetailsService(SmsUserDetailsService userDetailsService
) {this.userDetailsService
= userDetailsService
;}private void checkSmsCode(String mobile
, String code
) {final boolean flag
= userDetailsService
.checkSmsCode(mobile
, code
);if (!flag
) {throw new SmsAuthenticationException(SmsAuthenticationHandler.AuthenticationStatus.BAD_VERIFY_CODE);}}@Overridepublic boolean supports(Class<?> aClass
) {return SmsAuthenticationToken.class.isAssignableFrom(aClass
);}
}
模仿UserDetailsService
public interface SmsUserDetailsService extends UserDetailsService {boolean checkSmsCode(String mobile
, String code
);
}
創(chuàng)建配置類SmsCodeAuthenticationSecurityConfig
@Configuration
public class SmsCodeAuthenticationSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {@Autowiredprivate SmsAuthenticationHandler smsAuthenticationHandler
;@Autowiredprivate MobileUserDetailsServiceImpl mobileUserDetailsService
;@Overridepublic void configure(HttpSecurity http
) throws Exception {final SmsCodeAuthenticationFilter smsCodeAuthenticationFilter
= new SmsCodeAuthenticationFilter();smsCodeAuthenticationFilter
.setAuthenticationManager(http
.getSharedObject(AuthenticationManager.class));smsCodeAuthenticationFilter
.setAuthenticationDetailsSource(new ExtendWebAuthenticationDetailsSource());smsCodeAuthenticationFilter
.setAuthenticationSuccessHandler(smsAuthenticationHandler
);smsCodeAuthenticationFilter
.setAuthenticationFailureHandler(smsAuthenticationHandler
);final SmsAuthenticationProvider smsAuthenticationProvider
= new SmsAuthenticationProvider();smsAuthenticationProvider
.setUserDetailsService(mobileUserDetailsService
);http
.authenticationProvider(smsAuthenticationProvider
).addFilterAfter(smsCodeAuthenticationFilter
, UsernamePasswordAuthenticationFilter.class);}
}
創(chuàng)建配置類WebSecurityConfig繼承WebSecurityConfigurerAdapter,實(shí)現(xiàn)void configure(HttpSecurity http)方法。
@Overrideprotected void configure(HttpSecurity http
) throws Exception {http
.apply(smsCodeAuthenticationSecurityConfig
);http
.csrf().disable();}
總結(jié)
以上是生活随笔為你收集整理的security模仿密码登录实现短信验证码登录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。