Проблема

Поэтому я использую Spring boot в качестве бэкэнда и React JS в качестве интерфейса. Моя проблема заключается в том, что я всегда получаю перенаправление на http://localhost:8080/login, если аутентификация успешна . Это страница входа по умолчанию. В моем классе безопасности я настроил , что он будет перенаправлять на http://localhost:8080/authenticated, если аутентификация успешна , а если это не удается , перенаправлять на http://localhost:8080/notauthenticated. Если я наберу неправильное имя пользователя и пароль, все заработает. Он перенаправляет меня на http://localhost:8080/notauthenticated, но если я набираю правильное имя пользователя и пароль, он всегда перенаправляет меня на http://localhost:8080/login, но я получаю идентификатор сеанса, который работает . Если я ввожу неправильные учетные данные, я также получаю sessionid, но этот sessionid не работает , что имеет смысл. /authenticated и /notauthenticated - это всего лишь две конечные точки, которые просто возвращают ResponseEntity с логическим типом. Я также не понимаю, почему он не возвращает true или false. В почтальоне я получаю истину, если я аутентифицирован, но если нет, то он перенаправляет меня на страницу входа по умолчанию.

Код

Класс конфигурации безопасности Spring:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
                .allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
                        "Access-Control-Request-Headers", "Access-Control-Allow-Origin", "Access-Control-Allow-Method", "Set-Cookie")
                .exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
                .allowCredentials(true).maxAge(3600);
    }

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

    @Autowired
    UserDetailsServiceImpl userDetailsService;

    @Bean
    DaoAuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        return daoAuthenticationProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/", "index", "/css/*", "/js/*").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll()
                .loginProcessingUrl("/perform_login").permitAll()
                .defaultSuccessUrl("/authenticated", true)
                .usernameParameter("username")
                .passwordParameter("password")
                .failureUrl("/notauthenticated")
                .and()
                .logout()
                .logoutUrl("/perform_logout")
                .deleteCookies("JSESSIONID")
                .and()
                .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

}

2 конечные точки:

    @RequestMapping(value = "/authenticated", method = RequestMethod.GET)
    public ResponseEntity<Boolean> authenticate(){
        return new ResponseEntity<>(true, HttpStatus.OK);
    }

    @RequestMapping(value = "/notauthenticated", method = RequestMethod.GET)
    public ResponseEntity<Boolean> notAuthenticate(){
        return new ResponseEntity<>(false, HttpStatus.OK);
    }

Функция отправки в reactjs выглядит так:

   handleSubmit = async e => {
    e.preventDefault();
    const { username, password } = this.state;
    try {
      let res = await Axios({
        method: 'POST',
        headers: {
          "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
        },
        url: "/perform_login",
        data: "username=" + username + "&password=" + password
      });
      let redirectUrl = await res.request.responseURL;
      console.log(res);
      console.log(redirectUrl);
      if(redirectUrl !== 'http://localhost:8080/notauthenticated'){

      }
    } catch (err) {
      console.log(err);
    }
  };

0
user11524064 6 Янв 2020 в 19:03

1 ответ

Лучший ответ

У меня была такая же проблема, и я решил, добавив эту аннотацию в мой класс SpringWebApplication, для этого укажите Spring, чтобы удалить конфигурацию по умолчанию.

@ComponentScan( { "it.myapplication.controllers" } )
@EnableCaching
@SpringBootApplication( exclude = { SecurityAutoConfiguration.class } )
public class MyWebApplication{
    public static void main( String[] args ){
        SpringApplication.run( MyWebApplication.class, args );
    }
}

В моем классе WebSecurityConfig я ничего не менял

public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure( HttpSecurity http ) throws Exception
    {

    http
            .authorizeRequests()
            .antMatchers( "/","/home") 
            .permitAll() 
            .anyRequest()
            .authenticated().and()
            .formLogin().loginPage( "/login" )
            .permitAll().and().logout().permitAll();
    }

И я создал простую страницу login.html в разделе ресурсов / шаблонов, содержащую форму входа. Я использую тимелеаф в качестве механизма шаблонов.

 <body>
    <div th:if="${param.error}">
        Invalid username and password.
    </div>
    <div th:if="${param.logout}">
        You have been logged out.
    </div>
    <form th:action="@{/login}" method="post">
        <div><label> User Name : <input type="text" name="username"/> </label></div>
        <div><label> Password: <input type="password" name="password"/> </label></div>
        <div><input type="submit" value="Sign In"/></div>
    </form>
</body>

Я надеюсь это тебе поможет.

0
Lillo 21 Янв 2020 в 00:39
Если я сделаю это, я получаю сообщение об ошибке: «Описание: не удалось настроить источник данных: атрибут 'url' не указан, и не удалось настроить встроенный источник данных. Причина: не удалось определить подходящий класс драйвера»
 – 
user11524064
22 Янв 2020 в 21:03
Это не связано с предыдущей проблемой, проверьте application.properties, присутствует ли одна из этих строк: если вы используете локальный экземпляр сервера mysql: spring.datasource.driverClassName = com.mysql.jdbc.Driver, если вы используя БД в памяти, например h2: # spring.datasource.driverClassName = org.h2.Driver, дайте мне знать, если вы решите
 – 
Lillo
23 Янв 2020 в 22:37
Об атрибуте url, возможно, вам даже не хватает конфигурации url: spring.datasource.url = jdbc: mysql: // localhost: 3306 / my_database? UseSSL = false & useLegacyDatetimeCode = false & serverTimezone = UTC & zeroDateTimeBehavior = convertToNull
 – 
Lillo
23 Янв 2020 в 22:44
Я добавил URL-адрес в application.propeties, но аутентификация больше не работает, если я это сделаю.
 – 
user11524064
27 Янв 2020 в 13:57
Хорошо ... попробуйте опубликовать свой файл свойств. Ваш сервер mysql работает?
 – 
Lillo
28 Янв 2020 в 01:20