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();
}
}
}