首页 > 解决方案 > Spring Security 通过角色限制 URL 访问

问题描述

我正在尝试在这个小项目上实现 SpringSecurity 机制,这将限制角色与请求的 URL 的交互。

我有两个角色USERADMINUSER可以看到这些项目,但不能添加或删除它们,而ADMIN可以同时执行。

现在的问题是,以某种方式允许来自USER角色甚至未经身份验证的用户创建/删除/读取项目的请求。在我看来,我的应用程序在某处未正确配置。

安全配置:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password("{noop}12345").roles("USER").and()
                .withUser("admin").password("{noop}12345").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests()
                .antMatchers("api/**").hasRole("ADMIN")
                .antMatchers("api/items", "api/items/").hasRole("USER")
                .anyRequest().authenticated()
                .and().csrf().disable().headers().frameOptions().disable();
    }

}

控制器:

@RestController
public class ItemController {

    @Autowired
    private ItemService itemService;

    @GetMapping("/api/items")
    public List<Item> getItems() {
        return itemService.getAllItems();
    }

    @PostMapping(value = "/api/addItem",consumes = {"application/json"},produces = {"application/json"})
    @ResponseBody
    public Item addItem(@RequestBody Item item) {
        itemService.addItem(item);
        return item;
    }

    @DeleteMapping(value = "api/deleteItem/{id}")
    @ResponseBody
    public String deleteItem(@PathVariable int id) {
        itemService.deleteItem(id);
        return "Deleted";
    }
}

我正在向以下 URL 发送请求:

http://localhost:8080/api/items        // GET
http://localhost:8080/api/addItem      // POST
http://localhost:8080/api/deleteItem/4 // DELETE

标签: javaspringspring-security

解决方案


您是否尝试过在 antmatcher 模式中添加斜杠,例如:

antMatchers("/api/**").hasRole("ADMIN")

Spring文档提到:

注意:模式和路径必须都是绝对的或必须都是相对的,才能使两者匹配。因此,建议此实现的用户清理模式,以便在它们前面加上“/”,因为这在使用它们的上下文中是有意义的。

此外,Spring 安全性使用表达的所有匹配规则的第一个匹配。我建议将匹配器从最具体到不太具体重新排序,否则调用api/items将被匹配api/**器匹配,而不是被匹配api/items器匹配。

.antMatchers("/api/items", "api/items/").hasRole("USER")
.antMatchers("/api/**").hasRole("ADMIN")

推荐阅读