JSR 250 方法级安全性在 Spring MVC 中不起作用
JSR 250 method level security does not work in Spring MVC
我尝试从基于 @Configuration
的安全性转移到 JSR 250 方法级安全性。下面的代码工作如下:
访问我的页面是在 SecurityConfiguration.class
内的 configure(HttpSecurity http)
中配置的。每个人都可以访问 "all" 页面,如果有人尝试 "protected" 则显示默认登录页面,如果角色错误则显示 "Access denied" 消息。很好
现在,我想做完全相同的事情,但使用 JSR 250 注释。所以:
我删除了 configure(HttpSecurity http)
方法,添加到调度程序 servlet 上下文配置中
@EnableGlobalMethodSecurity(jsr250Enabled = true, proxyTargetClass = true, mode = AdviceMode.ASPECTJ, prePostEnabled=true)
显然 @PermitAll
和 @RolesAllowed
在控制器内部。
这些更改无法正常工作。如果我尝试访问任何页面,系统会询问我凭据(默认登录页面),如果我填写它们,那么我就可以以任何角色访问任何页面:(
我是不是忘记了什么?
提前感谢您提供的任何帮助,
马立克
应用程序上下文:
@Import(SecurityConfiguration.class)
public class AppConfiguration {
// entityManagerFactory, transactionManager, localValidatorFactoryBean, methodValidationPostProcessor
}
@Configuration
@EnableWebMvcSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("marek").password("123456").roles("USER");
auth.inMemoryAuthentication().withUser("bill").password("123456").roles("ADMIN");
auth.inMemoryAuthentication().withUser("james").password("123456").roles("SUPERADMIN");
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/all**").permitAll();
http.authorizeRequests().antMatchers("/protected/**").access("hasRole('ROLE_ADMIN')");
http.authorizeRequests().antMatchers("/confidential/**").access("hasRole('ROLE_SUPERADMIN')");
http.authorizeRequests().and().formLogin();
}
WebApplicationContext:
@Configuration
@EnableWebMvc
@EnableGlobalMethodSecurity(jsr250Enabled = true, proxyTargetClass = true, mode = AdviceMode.ASPECTJ, prePostEnabled=true)
@ComponentScan(basePackages = "xxx.xxx.controllers")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
// addInterceptors, addViewControllers, templateResolver, templateEngine, thymeleafViewResolver
}
控制器:
@Controller
public class HomeController {
@PermitAll
@RequestMapping(value = "/all**", method = RequestMethod.GET)
public String allPage(Model model) {
return "all";
}
@RolesAllowed("ADMIN")
@RequestMapping(value = "/protected**", method = RequestMethod.GET)
public String protectedPage(Model model) {
return "protected";
}
@RolesAllowed("SUPERADMIN")
@RequestMapping(value = "/confidential**", method = RequestMethod.GET)
public String superAdminPage(Model model) {
return "confidential";
}
}
依赖关系:
<appengine.target.version>1.9.18</appengine.target.version>
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
<javax.jsr250-api.version>1.0</javax.jsr250-api.version>
<spring.version>4.1.5.RELEASE</spring.version>
<spring.security.version>3.2.6.RELEASE</spring.security.version>
<spring.thymeleaf.version>2.1.4.RELEASE</spring.thymeleaf.version>
<aspectj.version>1.8.5</aspectj.version>
我注意到您的 @EnableGlobalMethodSecurity 注释使用代理模式 AdviceMode.ASPECTJ 但您的依赖项未列出 AspectJ。
如果您尝试使用 AspectJ 代理,则需要提供依赖项并添加配置以使用 AspectJ 编译器进行编译。
如果您不打算使用 AspectJ 代理,请尝试不使用 'mode = AdviceMode.ASPECTJ' 参数。
编辑 - 这可能并不明显。要使用 AspectJ 代理,您需要:
- 指定依赖项
- 提供 aspectj 插件配置以使用 AspectJ 编译器进行编译
这里有一个maven配置的例子:Running JDK8 for aspectj
这是 gradle 的一个:https://github.com/jigishpa/spring-samples/blob/master/aop/hello/build.gradle
我尝试从基于 @Configuration
的安全性转移到 JSR 250 方法级安全性。下面的代码工作如下:
访问我的页面是在 SecurityConfiguration.class
内的 configure(HttpSecurity http)
中配置的。每个人都可以访问 "all" 页面,如果有人尝试 "protected" 则显示默认登录页面,如果角色错误则显示 "Access denied" 消息。很好
现在,我想做完全相同的事情,但使用 JSR 250 注释。所以:
我删除了 configure(HttpSecurity http)
方法,添加到调度程序 servlet 上下文配置中
@EnableGlobalMethodSecurity(jsr250Enabled = true, proxyTargetClass = true, mode = AdviceMode.ASPECTJ, prePostEnabled=true)
显然 @PermitAll
和 @RolesAllowed
在控制器内部。
这些更改无法正常工作。如果我尝试访问任何页面,系统会询问我凭据(默认登录页面),如果我填写它们,那么我就可以以任何角色访问任何页面:(
我是不是忘记了什么?
提前感谢您提供的任何帮助, 马立克
应用程序上下文:
@Import(SecurityConfiguration.class)
public class AppConfiguration {
// entityManagerFactory, transactionManager, localValidatorFactoryBean, methodValidationPostProcessor
}
@Configuration
@EnableWebMvcSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("marek").password("123456").roles("USER");
auth.inMemoryAuthentication().withUser("bill").password("123456").roles("ADMIN");
auth.inMemoryAuthentication().withUser("james").password("123456").roles("SUPERADMIN");
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/all**").permitAll();
http.authorizeRequests().antMatchers("/protected/**").access("hasRole('ROLE_ADMIN')");
http.authorizeRequests().antMatchers("/confidential/**").access("hasRole('ROLE_SUPERADMIN')");
http.authorizeRequests().and().formLogin();
}
WebApplicationContext:
@Configuration
@EnableWebMvc
@EnableGlobalMethodSecurity(jsr250Enabled = true, proxyTargetClass = true, mode = AdviceMode.ASPECTJ, prePostEnabled=true)
@ComponentScan(basePackages = "xxx.xxx.controllers")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
// addInterceptors, addViewControllers, templateResolver, templateEngine, thymeleafViewResolver
}
控制器:
@Controller
public class HomeController {
@PermitAll
@RequestMapping(value = "/all**", method = RequestMethod.GET)
public String allPage(Model model) {
return "all";
}
@RolesAllowed("ADMIN")
@RequestMapping(value = "/protected**", method = RequestMethod.GET)
public String protectedPage(Model model) {
return "protected";
}
@RolesAllowed("SUPERADMIN")
@RequestMapping(value = "/confidential**", method = RequestMethod.GET)
public String superAdminPage(Model model) {
return "confidential";
}
}
依赖关系:
<appengine.target.version>1.9.18</appengine.target.version>
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
<javax.jsr250-api.version>1.0</javax.jsr250-api.version>
<spring.version>4.1.5.RELEASE</spring.version>
<spring.security.version>3.2.6.RELEASE</spring.security.version>
<spring.thymeleaf.version>2.1.4.RELEASE</spring.thymeleaf.version>
<aspectj.version>1.8.5</aspectj.version>
我注意到您的 @EnableGlobalMethodSecurity 注释使用代理模式 AdviceMode.ASPECTJ 但您的依赖项未列出 AspectJ。
如果您尝试使用 AspectJ 代理,则需要提供依赖项并添加配置以使用 AspectJ 编译器进行编译。
如果您不打算使用 AspectJ 代理,请尝试不使用 'mode = AdviceMode.ASPECTJ' 参数。
编辑 - 这可能并不明显。要使用 AspectJ 代理,您需要:
- 指定依赖项
- 提供 aspectj 插件配置以使用 AspectJ 编译器进行编译
这里有一个maven配置的例子:Running JDK8 for aspectj
这是 gradle 的一个:https://github.com/jigishpa/spring-samples/blob/master/aop/hello/build.gradle