Я пишу небольшое приложение для себя и хочу реализовать двухфакторную аутентификацию в Spring Boot. Для этого следуйте советам этой статьи: https://www.baeldung.com/spring-security-two-factor-authentication-with-soft-token
Столкнулся со следующими проблемами: 1) Мой код, написанный на основе этой статьи, не работает. Spring Security полностью игнорирует is2FaEnabled == true и в любом случае авторизует пользователя, даже если код не был введен.
Судя по журналам в этом потоке .authenticationDetailsSource (authenticationDetailsSource) даже go для проверка.
2) Как я могу реализовать следующее: во время авторизации сначала проверьте, включен ли 2FA, если да, то направьте пользователя на другой URL-адрес или откройте модуль с вводом и после правильного ввода кода, авторизовать его?
Вот мой исходный код:
CustomWebAuthenticationDetailsSource. java
@Component
public class CustomWebAuthenticationDetailsSource implements
AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
@Override
public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
return new CustomWebAuthenticationDetails(context);
}
}
CustomWebAuthenticationDetails. java
public class CustomWebAuthenticationDetails extends WebAuthenticationDetails {
@Getter
private String verificationCode;
public CustomWebAuthenticationDetails(HttpServletRequest request) {
super(request);
verificationCode = request.getParameter("code");
}
}
CustomAuthenticationProvider . java
public class CustomAuthenticationProvider extends DaoAuthenticationProvider {
@Autowired
private UserServiceImpl userServiceImpl;
private Logger logger = LoggerFactory.getLogger(CustomAuthenticationProvider.class);
@Override
public Authentication authenticate(Authentication auth)
throws AuthenticationException {
User user = userServiceImpl.findUserByEmail(auth.getName());
String verificationCode
= ((CustomWebAuthenticationDetails) auth.getDetails())
.getVerificationCode();
if ((user == null)) {
throw new BadCredentialsException("Invalid username or password");
}
if (user.getIs2FaEnabled()) {
Totp totp = new Totp(user.getTwoFaSecret());
if (!isValidLong(verificationCode) || !totp.verify(verificationCode)) {
throw new BadCredentialsException("Invalid verfication code");
}
}
Authentication result = super.authenticate(auth);
return new UsernamePasswordAuthenticationToken(
user, result.getCredentials(), result.getAuthorities());
}
private boolean isValidLong(String code) {
try {
Long.parseLong(code);
} catch (NumberFormatException e) {
return false;
}
return true;
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
WebSecurityConfig. java
Заранее спасибо!