预授权在控制器上不起作用 [英] PreAuthorize not working on Controller
问题描述
我正在尝试在方法级别定义访问规则,但是它一直无法正常工作.
I'm trying to define access rules at method-level but it's not working what so ever.
SecurityConfiguration
SecurityConfiguration
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().
withUser("user").password("user").roles("USER").and().
withUser("admin").password("admin").roles("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/v2/**").authenticated()
.and()
.httpBasic()
.realmName("Secure api")
.and()
.csrf()
.disable();
}
}
ExampleController
ExampleController
@EnableAutoConfiguration
@RestController
@RequestMapping({"/v2/"})
public class ExampleController {
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
@RequestMapping(value = "/home", method = RequestMethod.GET)
String home() {
return "Hello World";
}
}
每当我尝试使用user:user
访问/v2/home时,它执行得很好,是否由于用户"没有ROLE_ADMIN
而给我一个拒绝访问错误?
Whenever I try to access /v2/home using user:user
it executes just fine, shouldn't it give me an Access Denied error due to 'user' not having ROLE_ADMIN
?
我实际上是在考虑方法级别的访问规则,并坚持使用http()ant规则,但是我必须知道为什么它对我不起作用.
I'm actually thinking of ditching access rules at method-level and stick to http() ant rules, but I have to know why it's not working for me.
推荐答案
在控制器上使用PrePost注释的一个常见问题是Spring方法的安全性基于Spring AOP,默认情况下,该方法是通过JDK代理实现的.
A common problem with using PrePost annotations on controllers is that Spring method security is based on Spring AOP, which is by default implemented with JDK proxies.
这意味着它在服务层上可以正常工作,该服务层作为接口注入到控制器层中,但由于控制器通常不实现接口,因此在控制器层上将被忽略.
That means that it works fine on the service layer which is injected in controller layer as interfaces, but it is ignored on controller layer because controller generally do not implement interfaces.
以下是我的看法:
- 首选方式:在服务层上移动post post注释
- 如果您不能(或不想),请尝试让控制器实现包含所有带注释的方法的接口
- 最后一种方法是使用 proxy-target-class = true
这篇关于预授权在控制器上不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!