【问题标题】:antMatchers & permitAll doesn't let me visit the REST pointantMatchers & permitAll 不允许我访问 REST 点
【发布时间】:2020-04-04 17:11:06
【问题描述】:

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

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

顺便说一句,我尝试了/api/topics**,但效果不佳。

错误:

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

没有标记的结果(损坏的部分)。我想让它让我通过。

带有令牌的结果。它按预期工作:

@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 {

}

【问题讨论】:

    标签: spring-boot spring-security


    【解决方案1】:

    因为@EnableResourceServer默认会在order=3的时候添加自己的filterchain。至于WebSecurityConfigurerAdapter的实现,在order=100的时候会添加自己的filterchain,所以请求会先经过@set的filterchain 987654324@ 除非您提供令牌,否则一切都受到保护,这就是您得到这种行为的原因。尝试在WebSecurityConfigurerAdapter 实现中添加类似@Order(2) 注释的命令波纹管3。

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

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

    【讨论】:

      【解决方案2】:

      antMatchers 中的 URL 模式存在错误。

      默认情况下,/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

      【讨论】:

      • 还是不行:Full authentication is required to access this resource。我都试过了。实际上我在我测试过的问题中写了/api/topics**。其他东西可能会破坏它,但是
      猜你喜欢
      • 2014-09-02
      • 2019-09-27
      • 2018-01-31
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 2019-08-16
      • 2018-04-18
      相关资源
      最近更新 更多