antMatchers和permitAll不允许我访问REST点

时间:2020-04-04 17:11:06

标签: spring-boot spring-security

以下行不允许我在没有承载令牌的情况下访问GET: /api/topics。如果我应用令牌,它会起作用。我想念什么吗?是不是permitAll应该这样做?

.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 个答案:

答案 0 :(得分:1)

antMatchers中的网址格式有误。

默认情况下,/api/topics/**之类的模式与/api/topics不匹配。

它仅与/api/topics/匹配,并且斜杠后可以是零个或多个符号

要解决此问题,可以采用几种解决方案:

  1. 将现有antMatchers中的模式更改为下一个/api/topics**
  2. 使用mvcMatchers代替antMatchers。 mvcMatchers("/api/topics").permitAll()

mvcMatchers-将使用与Spring MVC相同的规则 匹配。例如,通常路径“ / path”的映射会 在“ /path”、“/path/”、“/path.html”等上匹配。

有关antMatchers的更多信息,请参见here

有关mvcMatchers的更多信息,请参见here

答案 1 :(得分:0)

因为@EnableResourceServer默认情况下会在order = 3处添加其过滤器链。对于WebSecurityConfigurerAdapter实现,它会在order = 100处添加其自己的过滤器链,因此,请求首先通过过滤器链由@EnableResourceServer设置,其中所有内容都受到保护,除非您提供令牌,这就是为什么您会得到这种行为。尝试在您的@Order(2)实现中添加像WebSecurityConfigurerAdapter这样的命令波纹管3。

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

有关更多信息,请阅读:Changing the Filter Order