【问题标题】:JSR 250 method level security does not work in Spring MVCJSR 250 方法级安全性在 Spring MVC 中不起作用
【发布时间】:2015-03-24 14:38:03
【问题描述】:

我尝试从基于 @Configuration 的安全性转移到 JSR 250 方法级安全性。下面的代码工作如下:

对我的页面的访问是在configure(HttpSecurity http) 内的SecurityConfiguration.class 中配置的。每个人都可以访问“全部”页面,如果有人尝试“受保护”,则显示默认登录页面,如果角色错误,则显示“访问被拒绝”消息。很好。

现在,我想做完全相同的事情,但使用 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>

【问题讨论】:

    标签: java spring spring-mvc spring-security jsr250


    【解决方案1】:

    我注意到您的 @EnableGlobalMethodSecurity 注释使用代理模式 AdviceMode.ASPECTJ 但您的依赖项没有列出 AspectJ。

    如果您尝试使用 AspectJ 代理,则需要提供依赖项并添加配置以使用 AspectJ 编译器进行编译。

    如果您不打算使用 AspectJ 代理,请尝试不使用“mode = AdviceMode.ASPECTJ”参数。

    编辑 - 这可能并不明显。要使用 AspectJ 代理,您需要:

    1. 指定依赖关系
    2. 提供 aspectj 插件配置以使用 AspectJ 编译器进行编译

    这里是一个 maven 配置示例:Running JDK8 for aspectj

    这是 gradle 的一个:https://github.com/jigishpa/spring-samples/blob/master/aop/hello/build.gradle

    【讨论】:

    • 对不起,我忘了把这个添加到帖子中,我在入围时错过了它我使用:org.aspectjaspectjrt${aspectj.version}
    • 但实际上.. 当我在控制器内部执行时检查堆栈跟踪时,我看不到中间的任何方面: HomeController.allPage(Model) line: 51 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43 Method.invoke(Object, Object...) line : 601 Runtime.invoke(Method, Object, Object[]) 行: 130
    • 是的......如果我删除这个依赖项哈哈,那么工作方式相同,所以可以肯定 AspectJ 没有完成它的工作
    • oki,解决了。我已经转移到 JDK 动态代理。不幸的是,这迫使我为我创建的每个控制器编写接口,但无论如何最好在我工作的非常严格的 GAE 环境中使用它们。最后要解决的是如何跳过@PermiAll 方法的登录页面,但这是一项单独的任务。
    • cool :-) 我没有使用 maven,但我有一个使用 AspectJ 代理的 gradle 项目。有兴趣的可以看看github.com/jigishpa/spring-samples/tree/master/aop/hello。看看 build.gradle。
    猜你喜欢
    • 2014-01-02
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    相关资源
    最近更新 更多