Spring Security возвращает ошибку 405 Request Method 'POST' Not Supported

244
27 июля 2021, 22:00

Я использую Spring Security и Spring MVC в своем проекте, и я пытаюсь сделать страницу авторизации, но, к сожалению, при нажатии на кнопку "Log in", появляется сообщение с ошибкой 405.

Версия Spring: 5.1.9.RELEASE

thymeleaf login html файл:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Custom Login Page</title>
</head>
<body>
<h2>Custom Login Page</h2>
<form th:action="@{/login}" method="POST">
    <label for="username">Username:</label>
    <input type="text" id="username" name="username" autofocus="autofocus" />
    <label for="password">Password:</label>
    <input type="password" id="password" name="password" />
    <input type="submit" value="Log in" />
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
</form>
</body>
</html>

Security Configuration файл:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    public WebSecurityConfig() {
        super();
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .successForwardUrl("/index")
            .loginProcessingUrl("/login")
            .failureForwardUrl("/error")
            .permitAll()
            .and()
            .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login")
            .permitAll()
            .and()
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER");
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("jim").password(passwordEncoder().encode("12345")).roles("ADMIN").and()
            .withUser("bob").password(passwordEncoder().encode("67890")).roles("USER");
    }
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Controller файл:

@Controller
public class MainController {
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public ModelAndView index() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        return modelAndView;
    }
    @RequestMapping(value = "/user/index", method = RequestMethod.GET)
    public ModelAndView userIndex() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("user/index");
        return modelAndView;
    }
    @RequestMapping(value = "/admin/index", method = RequestMethod.GET)
    public ModelAndView adminIndex() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("admin/index");
        return modelAndView;
    }
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ModelAndView loginPage() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("login");
        return modelAndView;
    }
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ModelAndView login(Authentication authentication) {
        ModelAndView modelAndView = new ModelAndView();
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        String userName = userDetails.getUsername();
        String password = userDetails.getPassword();
        if (userName.equals("jim") && password.equals("12345")) {
            modelAndView.setViewName("index");
        } else {
            modelAndView.setViewName("error");
        }
        return modelAndView;
    }
}

Подскажите, пожалуйста, что я упускаю? Заранее большое спасибо за ответ!

Answer 1

Скорее всего у вас "заблокирован" login. т.е. доступ к данной странице можно лишь получить тогда, когда авторизуетесь. Отсюда вам следует login-страницу сделать публичным:

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/", "/login", "/registration", "/change/**").permitAll()
                    .antMatchers("/admin/**").hasRole("ADMIN")
                    .antMatchers("/user/**").hasRole("USER")
                    .anyRequest()
                    .authenticated()

                    .and().formLogin()
                    .loginPage("/login")
                    .failureUrl("/error")
                    .defaultSuccessUrl("/index")
                    .usernameParameter("email")
                    .passwordParameter("password")

                    .and().logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/")

                    .and().exceptionHandling()
                    .accessDeniedPage("/access-denied");
        }
Answer 2

Вы используете Security, но между тем пишите сами логику аутентификации. Зачем?

.loginPage("/login") устанавливает начальную страницу с формой аутентификации. "/login" - этим путем замапен контроллер самого спринга, который осуществляет аутентификацию. Лучше изменить его на другой (например так: .loginPage("/auth"), и изменить путь в контроллере loginPage(). Свой контроллер login() уберите.

READ ALSO
Удаление элемента из ArrayList Java

Удаление элемента из ArrayList Java

У меня есть класс Worker и форма расчета ЗП

224
нужно найти месторасположение файла, по его названию

нужно найти месторасположение файла, по его названию

есть имя файла Chrome, нужно только по его названию, найти где файл находится

186
Как изменять переменные из функции main в других функциях?

Как изменять переменные из функции main в других функциях?

Хочу, чтобы переменная one приняла значение two в теле не основной функцииВ с++ на это есть указатели

188
Фрагменты ViewPager в фрагментах BottomNavigationView

Фрагменты ViewPager в фрагментах BottomNavigationView

В общем, есть фрагмент HomeFragment, который выбирается с помощью BottomNavigationViewВ этом фрагменте есть еще два фрагмента TabLayout\ViewPager фильмы и сериалы

273