使用Spring Security 3.2.5和Spring 4.1.2,100%Java配置
我们的webapp启用了全局方法安全性,并使用@PreAuthorize
注释了服务方法 - 一切都按预期工作。我正在尝试添加角色层次结构,但根本没有成功。这是我想要实现的层次结构:
尽管我付出了最大的努力,但是当做一些导致调用注释为@PreAuthorized("hasAuthority('ROLE_DEFAULT')")
以下是相关的配置代码:
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配置解决方案让我望而却步。
答案 0 :(得分:0)
我刚刚通过所有这些设置并在此回答同样的问题:Spring Boot + Spring Security + Hierarchical Roles
希望这有帮助。
答案 1 :(得分:0)
由于这个问题不断得到观点,我认为我会发布一个后续行动。问题似乎与行
有关 complexStartUpRoutine
我不记得为什么我这样写了层次结构,但它不正确。 API for that method因此处理相同的情况:
角色层次结构:ROLE_A&gt; ROLE_B和ROLE_B&gt; ROLE_C。
直接分配权限: ROLE_A。
可访问权限: ROLE_A,ROLE_B,ROLE_C。
最后很明显,分层模型并不适合我们的角色,所以我们改为实现映射到角色的更细粒度的权限集,如Spring Security Reference中所述:
对于更复杂的要求,您可能希望在应用程序所需的特定访问权限和分配给用户的角色之间定义逻辑映射,在加载用户信息时在两者之间进行转换。