antMatchers & allowAll не позволяет мне посетить пункт REST - PullRequest
0 голосов
/ 04 апреля 2020

Следующая строка не позволяет мне посетить GET: /api/topics без токена на предъявителя. Это работает, если я применяю токен. Я что-то пропустил? Разве не разрешено все это делать?

.antMatchers("/api/topics/**").permitAll()

Кстати, я пробовал с /api/topics**, но это тоже не сработало.

Ошибка:

{
    "error": "unauthorized",
    "error_description": "Full authentication is required to access this resource"
}

Результат без токена (сломанная часть). Я хочу, чтобы он пропустил меня.

enter image description here

Результат с токеном. Работает по назначению:

enter image description here

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/api/topics/**").permitAll()
                .antMatchers("/api/users/**").permitAll()
                .anyRequest().authenticated();
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
@RestController
@RequestMapping("/api/topics")
public class TopicController {

    @Autowired
    private TopicService topicService;

    @Autowired
    private UserService userService;

    @Autowired
    private TopicMapper topicMapper;

    /**
     * Gets all topics.
     *
     * @return the topics.
     */
    @GetMapping
    public ResponseEntity<List<TopicDTO>> getAll() {
        return ResponseEntity.ok(topicMapper.toTopicDTOs(topicService.getAll()));
    }

    /**
     * Gets topic by id.
     *
     * @param id the id.
     * @return the topic.
     */
    @GetMapping("/{id}")
    public ResponseEntity<TopicDTO> get(@PathVariable("id") Long id) {
        Optional<TopicEntity> topicEntity = topicService.get(id);
        return topicEntity.map(entity -> ResponseEntity.ok(topicMapper.toTopicDTO(entity))).orElseGet(() -> ResponseEntity.notFound().build());
    }

    /**
     * Creates a new topic.
     *
     * @param topicDTO the topic DTO.
     * @return the new topic DTO.
     */
    @PostMapping
    public ResponseEntity<TopicDTO> create(@RequestBody TopicDTO topicDTO) {
        UserEntity userEntity = userService.get(topicDTO.getUserId()).orElseThrow(() -> new IllegalArgumentException("User does not exist."));

        TopicEntity topicEntity = topicMapper.toTopicEntity(topicDTO);
        topicEntity.setId(null);
        topicEntity.setUser(userEntity);

        Optional<TopicEntity> createdTopicEntity = topicService.create(topicEntity);

        return createdTopicEntity.map(entity -> ResponseEntity.ok(topicMapper.toTopicDTO(entity))).orElseGet(() -> ResponseEntity.status(HttpStatus.CONFLICT).build());
    }

    /**
     * Updates an existing topic.
     * @param id the topic id.
     * @param topicDTO the topic DTO.
     * @return the updated topic DTO.
     */
    @PutMapping("/{id}")
    public ResponseEntity<TopicDTO> update(@PathVariable("id") Long id, @RequestBody TopicDTO topicDTO) {
        UserEntity userEntity = userService.get(topicDTO.getUserId()).orElseThrow(() -> new IllegalArgumentException("User does not exist."));

        TopicEntity topicEntity = topicMapper.toTopicEntity(topicDTO);
        topicEntity.setId(id);
        topicEntity.setUser(userEntity);

        Optional<TopicEntity> updatedTopicEntity = topicService.update(topicEntity);

        return updatedTopicEntity.map(entity -> ResponseEntity.ok(topicMapper.toTopicDTO(entity))).orElseGet(() -> ResponseEntity.badRequest().build());
    }

    /**
     * Deletes an existing topic.
     * @param id the topic id.
     * @return the status code.
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable("id") Long id) {
        if (topicService.get(id).isPresent()) {
            topicService.delete(id);
            return ResponseEntity.ok().build();
        }

        return ResponseEntity.notFound().build();
    }

}
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
                .inMemory()
                .withClient("trusted")
                .secret(bCryptPasswordEncoder.encode("secret"))
                .authorizedGrantTypes("password", "get_token", "refresh_token")
                .scopes("read", "write")
                .autoApprove(true)
                .accessTokenValiditySeconds(15 * 60)
                .refreshTokenValiditySeconds(30 * 60);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .authenticationManager(authenticationManager)
                .tokenStore(tokenStore);
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

}
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration {

}

Ответы [ 2 ]

1 голос
/ 04 апреля 2020

Поскольку @EnableResourceServer добавит свою цепочку фильтров по умолчанию в порядке = 3. Что касается реализации WebSecurityConfigurerAdapter, то добавит свою собственную цепочку фильтров в порядке = 100, в результате запрос сначала проходит через цепочку фильтров, установленную @EnableResourceServer где все защищено, если вы не предоставите токен, и именно поэтому вы получаете такое поведение. Попробуйте добавить порядок ниже 3 как @Order(2) аннотацию к вашей реализации WebSecurityConfigurerAdapter.

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@Order(2) <<---  add this
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
  ...
}

Для получения дополнительной информации читайте: Изменение порядка фильтрации

0 голосов
/ 04 апреля 2020

Ошибка в шаблонах URL в antMatchers.

По умолчанию шаблон, подобный /api/topics/**, не соответствует /api/topics.

Он соответствует только /api/topics/ и после sla sh может быть ноль или более символов

Для исправления этого случая может быть несколько решений:

  1. Изменить шаблон в существующих antMatchers на следующий /api/topics**
  2. Используйте mvcMatchers вместо antMatchers. mvcMatchers("/api/topics").permitAll()

mvcMatchers - будут использовать те же правила, которые Spring MVC использует для сопоставления. Например, часто сопоставление пути "/ path" будет совпадать с "/ path", "/ path /", "/path.html", et c.

Более подробную информацию о antMatchers можно найти здесь

Более подробную информацию о mvcMatchers можно найти здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...