Конфигурация Spring Security 6 с пользовательской формой входа в системуJAVA

Программисты JAVA общаются здесь
Anonymous
Конфигурация Spring Security 6 с пользовательской формой входа в систему

Сообщение Anonymous »

Я создаю приложение Spring Boot с конечной точкой «/admin», для доступа к которой требуется аутентификация; все остальные конечные точки должны быть доступны без аутентификации. Кроме того, аутентифицированный пользователь должен иметь полномочия «ADMIN» при доступе к любой из страниц в конечной точке «/admin». Я использую настраиваемую страницу входа, а также настраиваемый обработчик ошибок и настраиваемый обработчик успеха при входе в систему. Мне нужно иметь в виду, что в будущем могут быть добавлены другие безопасные конечные точки с другими конфигурациями безопасности (пример: конечная точка API с JWT аутентификация и авторизация).
Когда я пытаюсь войти в систему, я получаю следующую ошибку:

Код: Выделить всё

Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' is not supported]
Я думал, что обработка входа в систему выполняется автоматически Spring Security, но, возможно, я что-то упускаю?
Вот конфигурация безопасности :

Код: Выделить всё

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfiguration {
@Autowired
private LoginSuccessHandler loginSuccessHandler;

@Autowired
private LoginFailureHandler loginFailureHandler;

@Bean
public UserDetailsService userDetailsService() {
return new MyUserDetailsService();
}

@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
public AuthenticationManager authenticationManager() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder());
provider.setUserDetailsService(userDetailsService());

return new ProviderManager(provider);
}

@Bean
@Order(1)
public SecurityFilterChain adminFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.securityMatcher(new AntPathRequestMatcher("/admin/**"))
.authorizeHttpRequests(auth -> auth
.anyRequest()
.hasAuthority("ADMIN")
)
.formLogin(form -> form
.loginPage("/login")
.failureHandler(loginFailureHandler)
.successHandler(loginSuccessHandler)
.permitAll()
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
);

return http.build();
}

@Bean
public SecurityFilterChain defaultFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(def -> def
.requestMatchers(new AntPathRequestMatcher("/**"))
.permitAll()
);

return http.build();
}
Вот форма входа:

Код: Выделить всё







Log In

Метод формы контроллера:

Код: Выделить всё

@GetMapping(value="login")
public ModelAndView displayLoginPage() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("login");

return modelAndView;
}
LoginFailureHandler, где реализована логика неудачного входа в систему:

Код: Выделить всё

@Component
public class LoginFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Autowired
private UserRepository userRepository;

@Autowired
private LoginAttemptService loginAttemptService;

@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
String email = request.getParameter("email");
User user = userRepository.findByEmail(email);
String role = request.getParameter("role");

if (user != null) {
if (user.isEnabled()) {
if (user.getFailedAttempts() <  LoginAttemptService.MAX_FAILED_ATTEMPTS - 1) {
loginAttemptService.increaseFailedAttempts(user);
} else {
loginAttemptService.lock(user);
exception = new LockedException("Your account has been locked due to " + LoginAttemptService.MAX_FAILED_ATTEMPTS + " failed attempts." + " It will be unlocked after 24 hours.");
}
} else if (!user.isEnabled()) {
if (loginAttemptService.unlockWhenTimeExpired(user)) {
exception = new LockedException("Your account has been unlocked. Please try to login again.");
}
}
}

if (role.equals("USER")){
super.setDefaultFailureUrl("/login?errorUser");
} else {
super.setDefaultFailureUrl("/login?errorAdmin");
}
super.onAuthenticationFailure(request, response, exception);
}
}
LoginSuccessHandler, где реализована логика успешного входа в систему:

Код: Выделить всё

@Component
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Autowired
private LoginAttemptService loginAttemptService;

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
MyUserDetails userDetails = (MyUserDetails) authentication.getPrincipal();
User user = userDetails.getUser();
if (user.getFailedAttempts() > 0) {
loginAttemptService.resetFailedAttempts(user.getEmail());
}

String redirectURL = request.getContextPath();
String submittedRole = request.getParameter("role");

if (submittedRole.equals("ADMIN") && userDetails.hasRole("ADMIN")) {
redirectURL = "/admin/home";
} else if (submittedRole.equals("ADMIN") && !userDetails.hasRole("ADMIN")) {
redirectURL = "/login?wrongrole";
}

if (!user.isEnabled() && user.getLockTime() != null) {
redirectURL = "/login?disabled";
}

response.sendRedirect(redirectURL);
}
}
Я проверил различные решения на StackOverflow, в том числе это, которое показалось мне довольно близким к моему случаю:
Метод «POST» не поддерживается в Spring Security 6
а также документ о конфигурации Spring Java для нескольких конфигураций:
https://docs.spring.io/spring-security/ ... tpsecurity
Однако мне не удалось заставить мою часть входа работать должным образом.

Подробнее здесь: https://stackoverflow.com/questions/787 ... form-login

Вернуться в «JAVA»