我需要大家在安卓手机号码登录过程中提供帮助,我有一个应用程序,用户应该用手机号码发起登录,然后我需要在spring boot中使用基于OTP的验证号码。我有一个应用程序,用户需要用手机号码登录,然后我需要在spring boot中使用基于OTP的认证来验证该号码。验证成功后,JWT认证令牌将由spring boot应用程序生成,用户将使用该令牌访问其他API。
期待您的回复。
谢谢您的回复。
你需要一个额外的认证提供者。
@Slf4j
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
private OtpAuthenticationProvider otpAuthenticationProvider;
@Autowired
private JwtConfig jwtConfig;
@Autowired
private PasswordAuthenticationProvider passwordAuthenticationProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth
.authenticationProvider(otpAuthenticationProvider)
.authenticationProvider(passwordAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
// make sure we use stateless session; session won't be used to store user's state.
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// handle an authorized attempts
.exceptionHandling().authenticationEntryPoint((req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.and()
// Add a filter to validate the tokens with every request
.addFilterAfter(new JwtTokenAuthenticationFilter(jwtConfig), UsernamePasswordAuthenticationFilter.class)
// authorization requests config
.authorizeRequests()
// allow all who are accessing "auth" service
// allow /msg
.antMatchers("/oauth/token", "/v1/auth/**").permitAll()
// must be an admin if trying to access admin area (authentication is also required here)
// Any other request must be authenticated
.anyRequest().authenticated();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/webjars/**", "/swagger-ui.html**", "/favicon.ico",
"/swagger-resources**", "/swagger-resources/**", "/csrf**", "/v2/api-docs**");
}
@Bean
public JwtConfig jwtConfig() {
return new JwtConfig();
}
}
这里是OTP认证提供者 --
/**
* @author dv singh
*/
@Component
public class OtpAuthenticationProvider implements AuthenticationProvider {
private final AccountOtpService otpService;
private final AccountService accountService;
@Autowired
public OtpAuthenticationProvider(@Lazy AccountOtpService otpService, @Lazy AccountService accountService) {
this.otpService = otpService;
this.accountService = accountService;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
final OtpAuthenticationRequestToken request = (OtpAuthenticationRequestToken) authentication;
AccountOtp otpPrincipal = null;
// todo remove condition for prod, it for testing and development
if(!request.getToken().equals("123456")) {
try {
otpPrincipal = otpService.findByMobile(request.getMobile());
} catch (NoSuchElementException e) {
throw new BadCredentialsException("Invalid OTP");
}
if (!otpPrincipal.getOtp().equals(request.getToken()) || !otpPrincipal.getCreatedOn().isAfter(LocalDateTime.now()))
throw new BadCredentialsException("Invalid OTP");
}
Account account;
try {
account = accountService.findByMobile(request.getMobile());
} catch (NoSuchElementException e){
account = accountService.createJobSeeker(request.getMobile(), request.getDeviceToken());
}
// todo remove condition for prod
if(!request.getToken().equals("123456"))
otpService.clearOtp(otpPrincipal);
return new OtpAuthenticationToken(CustomAccountDetail.create(account));
}
@Override
public boolean supports(Class<?> authentication) {
return OtpAuthenticationRequestToken.class.isAssignableFrom(authentication);
}
}