Почему моя конечная точка / books / book POST возвращается несанкционированной

#spring #spring-boot #spring-security

#spring #spring-boot #spring-безопасность

Вопрос:

Я изучаю Spring Security и пытаюсь создать простой веб-сервис, который содержит название книги. Я пытаюсь реализовать свою безопасность, чтобы каждый мог использовать GET на моей конечной точке / books / book, а авторизованные пользователи могли отправлять сообщения в / books / book. По какой-то причине моя конечная точка POST сообщает, что мой пользователь авторизован, даже если я добавил заголовок аутентификации с правильными учетными данными.

Я просматривал разные примеры в Интернете, но, похоже, я просто не могу выяснить, где была моя ошибка.

Мой UserDetailsService содержит одного пользователя с именем batman, у которого есть роль ПОЛЬЗОВАТЕЛЯ, необходимая для публикации в / books / book

 @Component
public class CustomUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String string) throws UsernameNotFoundException {
        return User.withDefaultPasswordEncoder().username("batman").password("pass").roles("ADMIN", "USER").build();

    }

}
  

Мой SecurityConfig должен разрешать запрос GET для неавторизованных пользователей в / book / books. Эта часть работает.

Метод POST для /book / books должен быть разрешен только для авторизованных пользователей. Эта часть не работает и возвращает несанкционированный для всех.

 @EnableWebSecurity
public class CustomSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().and().cors().disable().authorizeRequests()
                .antMatchers(HttpMethod.GET, "/books/book").permitAll()
                .antMatchers(HttpMethod.POST, "/books/**").hasRole("ADMIN")
                .and()
                .httpBasic();
    }

}
  

Мой BookController выглядит следующим образом

 @RestController
@RequestMapping("/books")
public class BookController {
   @Autowired
   private BookService bookService;

   @GetMapping("/book")
   public ResponseEntity<Object> getAll() {
       return new ResponseEntity<>(bookService.getAll(), HttpStatus.OK);
   }

   @PostMapping("/book")
   public ResponseEntity<Object> add(@RequestBody Book book) {
       bookService.addBook(book);
       return ResponseEntity.ok().build();
   }
}

  

Мой книжный сервис

 @Service
public class BookService {

    @Autowired
    private BookRepository bookRepository;

    public Collection getAll() {
        return bookRepository.findAll();
    }

    public void addBook(Book book) {
        bookRepository.save(book);
    }

    public void deleteBook(Long id) {
        bookRepository.deleteById(id);
    }

    public void updateBook(Long id, Book book){
        bookRepository.findById(id).map((entry) -> {
            entry.setTitle(book.getTitle());
            bookRepository.save(book);
            return entry;
        });
    }

}
  

Мое хранилище книг

 @Repository
public interface BookRepository extends JpaRepository<Book, Long>{
    List<Book> findBookByTitle(String title);
}

  

Мой класс Book

 @AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Book {
    @Id
    @GeneratedValue
    private Long id;
    private String title;
}
  

Ожидаемый результат — неавторизованный запрос GET в / books / book и авторизованный запрос POST в / book / books

Комментарии:

1. Я отправляю токен через postman и использую базовую аутентификацию. Результат, который я получаю, имеет http-статус 403, что означает, что он неавторизован.

Ответ №1:

Вы используете Spring Boot?

Одна вещь, которая мне кажется странной, заключается в том, что вы ничего не делаете со своим CustomUserDetailsService.

попробуйте добавить в CustomSecurityConfig

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

Комментарии:

1. Решение не работает. Я автоматически подключаю customUserDetaulsService, чтобы Spring IOC автоматически обрабатывал объект для меня.

Ответ №2:

Проблема была в версии моих зависимостей Spring. Когда я обновил версию, проблема больше не возникала.