【发布时间】:2015-02-15 03:08:58
【问题描述】:
使用 Spring Security 3.2.5 和 Spring 4.1.2,100% Java 配置
我们的 web 应用启用了全局方法安全性,并使用 @PreAuthorize 注释了服务方法 - 一切都按预期工作。我正在尝试添加角色层次结构并且根本没有成功。这是我想要实现的层次结构:
- ROLE_ADMIN 可以访问 ROLE_USER 可以访问的所有方法。
- ROLE_USER 可以访问 ROLE_DEFAULT 可以访问的所有方法。
尽管我尽了最大努力,但具有 ROLE_ADMIN 的用户在执行导致调用带有 @PreAuthorized("hasAuthority('ROLE_DEFAULT')") 注释的方法的操作时收到 403
下面是相关配置代码:
AppInitializer
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class[]
{
AppConfig.class, SecurityConfig.class
};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return new Class[]
{
MvcConfig.class
};
}
// other methods not shown for brevity
}
AppConfig.java
@Configuration
@ComponentScan(basePackages={"myapp.config.profile", "myapp.dao", "myapp.service", "myapp.security"})
public class AppConfig
{
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth,
AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> detailSvc) throws Exception
{
PreAuthenticatedAuthenticationProvider authProvider = new PreAuthenticatedAuthenticationProvider();
authProvider.setPreAuthenticatedUserDetailsService(detailSvc);
auth.authenticationProvider(authProvider);
}
// other methods not shown for brevity
}
SecurityConfig.java
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
PKIAuthenticationFilter pkiFilter = new PKIAuthenticationFilter();
pkiFilter.setAuthenticationManager(authenticationManagerBean());
http.authorizeRequests()
.antMatchers("/app/**").fullyAuthenticated()
.and()
.anonymous().disable()
.jee().disable()
.formLogin().disable()
.csrf().disable()
.x509().disable()
.addFilter(pkiFilter)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
public void configure(WebSecurity web) throws Exception
{
// ignore everything but /app/*
web.ignoring().regexMatchers("^(?!/app/).*");
}
}
MvcConfig.java
@Configuration
@EnableWebMvc
@ComponentScan({"myapp.controller"})
public class MvcConfig extends WebMvcConfigurerAdapter
{
// resource handlers, content negotiation, message converters configured here
}
在与SecurityConfig 相同的包中(因此它是AppConfig 组件扫描的一部分)我有这个类:
GlobalMethodSecurityConfig.java
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration
{
@Bean
public RoleHierarchy roleHierarchy()
{
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER > ROLE_DEFAULT");
return roleHierarchy;
}
@Bean
public RoleVoter roleVoter()
{
return new RoleHierarchyVoter(roleHierarchy);
}
@Bean
@Override
protected AccessDecisionManager accessDecisionManager()
{
return new AffirmativeBased(Arrays.asList(roleVoter()));
}
// The method below was added in an attempt to get things working but it is never called
@Override
protected MethodSecurityExpressionHandler createExpressionHandler()
{
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
handler.setRoleHierarchy(roleHierarchy());
return handler;
}
}
在另一次尝试中,我进行了 AppConfig 扩展 GlobalMethodSecurityConfiguration,但具有 ROLE_ADMIN 的用户无法调用需要 ROLE_DEFAULT 访问权限的方法。
我确定我在某处错误地配置了某些东西,但尽管阅读了有关使用角色层次结构配置全局方法安全性的所有内容,但我无法弄清楚我哪里出错了。看来使用 XML 配置这将是微不足道的,但 Java 配置解决方案却让我望而却步。
【问题讨论】:
-
这不是对您问题的确切答案,但这是多年来对我有用的方法:stackoverflow.com/a/22612076/280244
标签: java spring security spring-mvc spring-security