Spring-security блокирует анонимные пользователи от извлечения данных из MongoDB

У меня есть веб-приложение Spring Boot, которое использует Spring Security. Страница index.html содержит вызов метода (POST) для контроллера, который загружает объекты из MongoDB в ArrayList и возвращает его, чтобы его можно было отобразить на первой странице.

Похоже, что Spring Security предотвращает POST-запросы для анонимных пользователей. Если я сначала войду в систему, чтобы вызвать метод "/loadContent", и тем самым выйду из системы, все будет хорошо. Я передаю токены CSRF перед вызовом метода.

Мой "WebSecurityConfig":

protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/", "/loadContent")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
            .logout()
            .permitAll()
            .and()
            .exceptionHandling()
            .accessDeniedPage("/403");
}

2 ответа

Оказалось опечаткой в ​​области @RequestMapping контроллера. Большое спасибо за вашу помощь.

CSRF включен по умолчанию в весенней безопасности.

Возможное решение - отключить его вручную (см. Последнюю строку в коде ниже).

protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/", "/loadContent")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
            .logout()
            .permitAll()
            .and()
            .exceptionHandling()
            .accessDeniedPage("/403")
            .and().csrf().disable();
}

Обновить:

Если вы хотите использовать csrf, который я рекомендую, возможно, подумайте о защите дополнительной конечной точки REST, например, начиная с / api /.

В приведенном ниже примере эти конечные точки защищены с использованием базовой авторизации для пользователя с именем api, но вы можете легко изменить его, чтобы анонимные пользователи могли запрашивать ресурсы:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
     @Autowired
     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("api").password("api").roles("API").and()
                .withUser("user").password("user").roles("USER").and()
                .withUser("admin").password("admin").roles("USER", "API", "ADMIN");
     }

     @Configuration
     @Order(1) // higher order = lower priority
     public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter{

         @Override
         protected void configure(HttpSecurity http) throws Exception {
            // no csrf when communicating directly with the backend api
             http
                 .antMatcher("/api/**")
                     .authorizeRequests()
                         .anyRequest().hasAnyRole("API")
                         .and()
                 .httpBasic()
                 .and()
                 .csrf().disable();
             http.sessionManagement().disable();

         }
     }

     @Configuration
     @Order(2) // higher order = lower priority
     public static class UIWebSecurityConfig extends WebSecurityConfigurerAdapter {
       @Override
        protected void configure(HttpSecurity http) throws Exception {
           http.authorizeRequests() 
                .antMatchers("/**").hasAnyRole("USER", "ADMIN").anyRequest().authenticated();

           http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
           http.httpBasic().disable();
        }
     }
}
Другие вопросы по тегам