Используя почтальон, я могу получить список пользователей с запросом на получение: http://localhost:8080/users.
Но когда я отправляю почтовый запрос на тот же адрес, я получаю ошибку 403.
@RestController
public class UserResource {
@Autowired
private UserRepository userRepository;
@GetMapping("/users")
public List<User> retrievaAllUsers() {
return userRepository.findAll();
}
@PostMapping("/users")
public ResponseEntity<Object> createUser(@RequestBody User user) {
User savedUser = userRepository.save(user);
URI location = ServletUriComponentsBuilder.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(savedUser.getId())
.toUri();
return ResponseEntity.created(location).build();
}
}
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
/*@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}*/
/*@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and().authorizeRequests()
.antMatchers("/users/**").hasRole("ADMIN")
.and().csrf().disable().headers().frameOptions().disable();
}*/
}
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private String password;
@Enumerated(EnumType.STRING)
private Role role;
// TODO which cna be removed
public User() {
super();
}
public User(Long id, String name, String password, Role role) {
this.id = id;
this.name = name;
this.password = password;
this.role = role;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
INSERT INTO user VALUES (1, 'user1', 'pass1', 'ADMIN');
INSERT INTO user VALUES (2, 'user2', 'pass2', 'USER');
INSERT INTO user VALUES (3,'user3', 'pass3', 'ADMIN')
РЕДАКТИРОВАТЬ
РЕДАКТИРОВАТЬ 2
добавил удаление, но тоже дает 403?
@DeleteMapping("/users/{id}")
public void deleteUser (@PathVariable long id) { userRepository.deleteById (id); }
редактировать 4
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/users/**").permitAll();
}
}
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
есть ли трассировка стека, например Access is denied или что-то в этом роде?
@benjaminc я их не вижу, и я отключил авторизацию, так что не знаю, зачем они нужны?
@ ab11, поскольку используется @EnableWebSecurity, попробуйте отключить поддержку csrf .csrf().disable()
@drowny ты прав, он работал, когда я добавил .and().csrf().disable();




403 означает, что у вас нет авторизации. Даже если вы закомментировали свой метод, ваш код все равно будет предварительно настроен с безопасным доступом по умолчанию.
Можете добавить:
http.authorizeRequests()
.antMatchers("/users/**").permitAll();
ОБНОВЛЕНИЕ: Конфигурация с отключенным csrf:
http.csrf()
.ignoringAntMatchers("/users/**")
.and()
.authorizeRequests()
.antMatchers("/users/**").permitAll();
спасибо, я обновил свой SecruityConfig, но получаю тот же 403 при удалении и создании. пожалуйста, посмотрите мои последние изменения с моим новым SecurityConfig. Может ли это относиться к классу Application? Я также включил его источник
добавьте также http.csrf (). disable (); также из ваших снимков экрана вы пытаетесь опубликовать список пользователей, и в вашем методе у вас есть только один пользователь.
@EnableWebSecurity включает весеннюю безопасность и по умолчанию включает поддержку csrf, вы должны отключить ее, чтобы предотвратить ошибки 403.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
Или отправляйте токен csrf с каждым запросом.
Примечание: отключение csrf делает приложение менее безопасным, лучше всего отправить токен csrf.
Пожалуйста, сконфигурируйте ваш http следующим образом:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//configureothers if u wants.
.csrf().disable();
}
Пожалуйста, прочтите больше CSRF
Когда вы используете весеннюю загрузку с весенней безопасностью, и если вы обращаетесь к своим API (POST, PUT, DELETE) из Postman или чего-то еще, они не будут доступны, и ошибка связана с авторизацией, например, запрещено 403.
Поэтому в этом случае вам необходимо отключить функцию csrf для запуска и тестирования API из Postman.
Ответ, предоставленный @benjamin c, правильный. Вы должны добавить класс с этой конфигурацией, которая будет работать.
Убедитесь, что вы удаляете это при добавлении кода в производство. Защита CSRF необходима, и вы должны сохранить ее в функции безопасности.
Я просто расширяю его ответ для получения более подробной информации, предоставляя полную информацию о классе. Моим требованием было просто протестировать API из Postman, поэтому я добавил этот класс и смог протестировать API из Postman.
Но после этого я добавил классы Spring Junit для проверки своих функций и удалил этот класс.
@Configuration
@EnableWebSecurity
public class AppWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().permitAll();
}
}
Надеюсь, это кому-то поможет.
Эта конфигурация в классе SecurityConfig помогла мне решить эту проблему:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
Почтальон иногда делает хитрые вещи, чтобы заставить себя работать. Вы сравнивали заголовки в каждом запросе, чтобы увидеть, есть ли какие-либо различия?