为了授权请求,我们覆盖了configure(HttpSecurity)
方法,我们提到访问我们想要哪个角色的API。但是我们没有提到的API可以在不登录的情况下访问。为什么会有这种行为?
我没有为API编写permitAll()
,为什么这是默认行为?
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasAnyRole("ADMIN", "USER")
.antMatchers("/").hasRole("USER")
.and()
.formLogin();
}
}
在这段代码中,admin
API可以通过管理员角色访问,user
API可以通过管理员和用户角色访问,而/
API可以通过用户角色访问并且还有一个我没有提到的API/student
,我可以在不登录的情况下访问它。
问题是我怎么没有为学生API编写permitAll()
方法。
为了保护未在配置方法中配置的API,必须添加行.anyRequest().denyAll()
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasAnyRole("ADMIN", "USER")
.antMatchers("/").hasRole("USER")
.anyRequest().denyAll()
.and()
.formLogin();
}
}
对于每个需要保护的请求,而不在配置方法中进行配置
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
);
}
将此行.antMatchers("/").hasRole("USER")
更改为此行.anyRequest().hasRole("USER")
。
只检查已配置的URL。如果不配置URL,则根本不会对其进行检查。
因此,您应该添加一个配置,检查所有其他URL,请参阅Spring Security Reference:
11.2.使用FilterSecurityInterceptor授权HttpServlet请求
[…]
protected void configure(HttpSecurity http) throws Exception { http // ... .authorizeRequests(authorize -> authorize 1 .mvcMatchers("/resources/**", "/signup", "/about").permitAll() 2 .mvcMatchers("/admin/**").hasRole("ADMIN") 3 .mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") 4 .anyRequest().denyAll() 5 ); }
1指定了多个授权规则。每一条规则都是按照它们被宣布的顺序来考虑的。
2我们指定了多个URL模式,任何用户都可以访问。具体地说,如果URL以"开头,则任何用户都可以访问请求/资源/";,等于"/"注册";,或等于"0"/关于";。
3任何以"/admin/";将被限制为具有角色"的用户;ROLE_ADMIN";。您会注意到,由于我们调用的是hasRole方法,因此不需要指定";ROLE_";前缀
4任何以"/db/";要求用户同时具有";ROLE_ADMIN";以及";ROLE_DBA";。您会注意到,由于我们使用的是hasRole表达式,因此不需要指定";ROLE_";前缀
5任何尚未在上匹配的URL都将被拒绝访问。如果您不想意外忘记更新授权规则,这是一个很好的策略。