SpringBoot + method based hierarchical roles secur

2020-05-08 08:14发布

I added method-based security and added role hierarchy. I keep getting the following exception during build:

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

I tried a lot of different configuration alternatives and none works... Here is my basic web security configuration class (I added role hierarchy-related beans as you see):

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

(...)

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
            .csrf()
            .disable()
            (...)
            .expressionHandler(webExpressionHandler())
            (...)
            .anyRequest().authenticated();

    httpSecurity
            .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}

@Bean
public SecurityExpressionHandler<FilterInvocation> webExpressionHandler() {
    DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
    defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy());
    return defaultWebSecurityExpressionHandler;
}

@Bean
public RoleHierarchy roleHierarchy() {
    RoleHierarchyImpl r = new RoleHierarchyImpl();
    r.setHierarchy(Role.getHierarchy());
    return r;
}

(...)

}

Here is the separate config file that I created basing on this thread:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    @Autowired
    private RoleHierarchy roleHierarchy;

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = (DefaultMethodSecurityExpressionHandler) super.createExpressionHandler();
        expressionHandler.setRoleHierarchy(roleHierarchy);
        return expressionHandler;
    }
}

I struggled with this for many hours. The related topics I tried are here:

Every help appreciated!

1条回答
小情绪 Triste *
2楼-- · 2020-05-08 08:57

OK, found it.

I played around with the class annotations and came to a simple solution: I removed @EnableGlobalMethodSecurity from GlobalMethodSecurityConfig and moved it to WebSecurityConfiguration, where it was before. So it looks like this:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { (...) }

and this:

@Configuration
public class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration { (...) }

The most interesting part is that the accepted answer from here advises what didn't work for me.

查看更多
登录 后发表回答