自定义RoleHierarchy不能与Spring Boot Web应用程序中的方法安全性一起使用

时间:2015-09-14 13:49:28

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

我正在创建自定义角色层次结构,并尝试将其与基于Web的安全性和方法级别安全性一起使用。这是一个Spring Boot Web应用程序。

我的配置文件:

@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled=true,prePostEnabled=true)
public class Application {

  public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
  }
}

SecurityConfig:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Autowired
ApplicationContext applicationContext;

@Override
public void configure(WebSecurity web) throws Exception {
    web
        .ignoring()
            .antMatchers("/resources/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .formLogin()
            .loginPage("/signin.html")
            .loginProcessingUrl("/signin/authenticate")
            .failureUrl("/signin?param.error=bad_credentials")
        .and()
            .logout()
                .logoutUrl("/signout")
                .deleteCookies("JSESSIONID")
        .and()
            .authorizeRequests()
                .expressionHandler(webExpressionHandler())
                .antMatchers("/signin**","/user/**","/admin/**", "/favicon.ico", "/resources/**", "/auth/**", "/signin/**", "/signup/**").permitAll()
                .antMatchers("/doc/**").hasRole("MOD").anyRequest().authenticated()
        .and()
            .apply(springSocialConfigurer())        
        .and()
            .rememberMe();
}
//Some more code for Spring Social integration
@Bean
public RoleHierarchy roleHierarchy() {
    RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
    roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_MOD > ROLE_USER > ROLE_GUEST");
    return roleHierarchy;
}

private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() {
    DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
    defaultWebSecurityExpressionHandler.setApplicationContext(applicationContext);
    defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy());
    return defaultWebSecurityExpressionHandler;
}

@Bean
public RoleHierarchyVoter roleHierarchyVoter() {
  return new RoleHierarchyVoter(roleHierarchy());
}

GlobalMethodSecurityConfig

@Configuration
public class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {

@Autowired
private RoleHierarchy roleHierarchy;
@Autowired
ApplicationContext applicationContext; 

@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
    System.out.println("Method Security configured");
    DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
    expressionHandler.setApplicationContext(applicationContext);
    expressionHandler.setRoleHierarchy(roleHierarchy);
    return expressionHandler;
}

}

现在,我注意到方法createExpressionHandler()永远不会被调用。那可能是因为我在Application类中添加了注释@EnableGlobalMethodSecurity? 如果我将注释放在GlobalMethodSecurityConfig类上,那么该方法将被调用,但是当我运行该程序时,我得到一个异常,其中说:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'defaultServletHandlerMapping' threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling

我无法弄清楚我在这里做错了什么。请帮忙。

编辑1 -------------

好的,我想我有一些想法,发生了什么。需要尽早配置Spring Security过滤器。因此,将RoleHierarchy Bean的创建移动到单独的配置文件可能会解决问题。我刚刚这样做了,我能够成功编译和运行代码。我在其他Configuration类中有自动装配的RoleHierarchy。自定义角色ROLE_MOD也可以。但是,问题还没有解决。

由于ROLE_MOD高于层次结构中的ROLE_USER,因此具有ROLE_MOD的用户是否有资格访问有权访问ROLE_USER的方法?

@PreAuthorize("hasRole('ROLE_USER')")

这对于使用ROLE_MOD的用户不起作用,我得到一个AccessDeniedException。我想知道这是否是配置自定义角色层次结构的正确方法。请帮帮我。

编辑2 -------------

好的,我对定义自定义角色层次结构的方式做了一些改动。 我改成了:

roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_MOD and ROLE_MOD > ROLE_USER and ROLE_USER > ROLE_GUEST");

现在一切正常!谢谢你给我一个大声思考的空间!

0 个答案:

没有答案