min*_*uno 7 java spring spring-mvc spring-security
首先,我是Java Spring Framework的新手.如果我没有提供足够的信息,请原谅我.我试图将RoleHierarchy添加到我的应用程序中,但它不起作用.以下是我尝试过的代码.
SecurityConfig.java
// These config is try to set up a user Role Hierarchy
@Bean
public RoleHierarchy roleHierarchy() {
System.out.println("arrive public RoleHierarchy roleHierarchy()");
RoleHierarchyImpl r = new RoleHierarchyImpl();
r.setHierarchy("ROLE_ADMIN > ROLE_STAFF");
r.setHierarchy("ROLE_STAFF > ROLE_USER");
r.setHierarchy("ROLE_DEVELOPER > ROLE_USER");
r.setHierarchy("ROLE_USER > ROLE_GUEST");
return r;
}
@Bean
public AffirmativeBased defaultAccessDecisionManager(RoleHierarchy roleHierarchy){
System.out.println("arrive public AffirmativeBased defaultAccessDecisionManager()");
List<AccessDecisionVoter> decisionVoters = new ArrayList<>();
// webExpressionVoter
WebExpressionVoter webExpressionVoter = new WebExpressionVoter();
DefaultWebSecurityExpressionHandler
expressionHandler = new DefaultWebSecurityExpressionHandler();
expressionHandler.setRoleHierarchy(roleHierarchy);
webExpressionVoter.setExpressionHandler(expressionHandler);
decisionVoters.add(webExpressionVoter);
decisionVoters.add(roleHierarchyVoter(roleHierarchy));
// return new AffirmativeBased(Arrays.asList((AccessDecisionVoter) webExpressionVoter));
return new AffirmativeBased(decisionVoters);
}
@Bean
public RoleHierarchyVoter roleHierarchyVoter(RoleHierarchy roleHierarchy) {
System.out.println("arrive public RoleHierarchyVoter roleHierarchyVoter");
return new RoleHierarchyVoter(roleHierarchy);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// skipping some codes
http
// skipping some codes
.accessDecisionManager(defaultAccessDecisionManager(roleHierarchy()))
// skipping some codes
}
Run Code Online (Sandbox Code Playgroud)
MethodSecurityConfig.java
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Inject
private SecurityConfig securityConfig;
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return securityConfig.authenticationManagerBean();
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
System.out.println("arrive protected MethodSecurityExpressionHandler createExpressionHandler()");
DefaultMethodSecurityExpressionHandler d = new DefaultMethodSecurityExpressionHandler();
d.setRoleHierarchy(securityConfig.roleHierarchy());
return d;
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个UserDetailsServiceImpl implements UserDetailsService提供principal,Authentication和GrantedAuthority
最后我有一些API:
@PreAuthorize("hasRole('ROLE_STAFF')")
@RequestMapping(value = "/api/v1/contactUs", method = RequestMethod.GET)
@PreAuthorize("hasRole('ROLE_DEVELOPER')")
@RequestMapping(value = "/api/v1/system", method = RequestMethod.GET)
Run Code Online (Sandbox Code Playgroud)
现在问题是如果我以ROLE_STAFF,ROLE_DEVELOPER,ROLE_ADMIN身份登录,我得到了以下结果.
| API | ROLE_STAFF | ROLE_DEVELOPER | ROLE_ADMIN |
|-----------|------------|----------------|------------|
| contactUs | 200 | 403 | 403 |
| system | 403 | 200 | 403 |
Run Code Online (Sandbox Code Playgroud)
你可以看到ROLE_STAFF并且ROLE_DEVELOPER工作得很好.但我想要ROLE_ADMIN作为两者的超级角色而且它不起作用.
仅供参考,我使用的是spring-security 3.2.5.RELEASE
min*_*uno 16
问题出在RoleHierachy中,它应该是这样的:
@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl r = new RoleHierarchyImpl();
r.setHierarchy("ROLE_ADMIN > ROLE_STAFF and ROLE_ADMIN > ROLE_DEVELOPER and ROLE_STAFF > ROLE_USER and ROLE_DEVELOPER > ROLE_USER");
return r;
}
Run Code Online (Sandbox Code Playgroud)
保持呼叫setHierarchy()将覆盖之前的设置
Lor*_*ton 13
每次我想用Spring Security和Java配置实现角色层次结构时,我都使用以下方法:
我们必须在上下文中添加一个RoleHierarchyImpl bean(你看,我使用多个角色来构建一个层次结构):
@Bean
public RoleHierarchyImpl roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_DBA ROLE_DBA > ROLE_USER ");
return roleHierarchy;
}
Run Code Online (Sandbox Code Playgroud)然后我们需要创建Web表达式处理程序以将获得的层次结构传递给它:
private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() {
DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy());
return defaultWebSecurityExpressionHandler;
}
Run Code Online (Sandbox Code Playgroud)最后一步是将expressionHandler添加到http.authorizeRequests()中:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.expressionHandler(webExpressionHandler())
.antMatchers("/admin/**").access("(hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')) and isFullyAuthenticated()")
.antMatchers("/dba").access("hasRole('ROLE_DBA') and isFullyAuthenticated()")
.antMatchers("/dba/**").access("hasRole('ROLE_USER')")
.and()
.requiresChannel()
.antMatchers("/security/**").requiresSecure()
.anyRequest().requiresInsecure()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?auth=fail")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/admin")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.deleteCookies("remember-me")
.invalidateHttpSession(true)
.logoutSuccessUrl("/index")
.permitAll()
.and()
.csrf()
.and()
.rememberMe().tokenValiditySeconds(1209600)
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.anonymous().disable()
.addFilter(switchUserFilter());
}
Run Code Online (Sandbox Code Playgroud)结果:在这个特定的例子中,我们在使用admin用户(ROLE_ADMIN)登录后尝试访问/ dba部分.在我们创建层次结构之前,我们有一个访问被拒绝的结果,但现在我们可以毫无问题地访问此部分.
注意:接受的答案不适用于最新版本的 Spring security(我认为自 5.2.1 版以来)。这是因为“和”(ROLE_1 > ROLE_2和ROLE_2 > ROLE_3)符号从来都不是官方标准。你可以写下每个单词而不是“and”,它在过去的版本中仍然有效。
相反,在新版本中,您现在应该使用 '\n'(新行),例如 ROLE_1 > ROLE_2\nROLE2 > ROLE_3 ...
| 归档时间: |
|
| 查看次数: |
9722 次 |
| 最近记录: |