之前的文章中,各個角色之間不具備任何關係,但一般來說角色之前是有關係的,例如 ROLE_admin 一般既有 admin 的權限,又具有 user 的權限。下面介紹如何配置這種角色之間相互繼承的關係。
五、角色繼承
1、配置角色關係
要配置角色繼承關係,只需在 Spring Security 的配置類中提供一個 RoleHierarchy 即可。下面高亮代碼含義:
- ROLE_dba 擁有所有的權限
- ROLE_admin 具有 ROLE_user 的權限
- ROLE_user 則是一個公共角色
@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
// 指定密碼的加密方式
@SuppressWarnings("deprecation")
@Bean
PasswordEncoder passwordEncoder(){
// 不對密碼進行加密
return NoOpPasswordEncoder.getInstance();
}
// 配置用戶及其對應的角色
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("root").password("123").roles("DBA")
.and()
.withUser("admin").password("123").roles("ADMIN")
.and()
.withUser("hangge").password("123").roles("USER");
}
// 配置角色繼承關係
@Bean
RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
String hierarchy = "ROLE_DBA > ROLE_ADMIN > ROLE_USER";
roleHierarchy.setHierarchy(hierarchy);
return roleHierarchy;
}
// 配置 URL 訪問權限
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 開啓 HttpSecurity 配置
.antMatchers("/db/**").hasRole("DBA") // db/** 模式URL需DBA角色
.antMatchers("/admin/**").hasRole("ADMIN") // admin/** 模式URL需ADMIN角色
.antMatchers("/user/**").hasRole("USER") // user/** 模式URL需USER角色
.anyRequest().authenticated() // 用戶訪問其它URL都必須認證後訪問(登錄後訪問)
.and().formLogin().loginProcessingUrl("/login").permitAll() // 開啓表單登錄並配置登錄接口
.and().csrf().disable(); // 關閉csrf
}
}
2、運行測試
(1)啓動項目,我們使用 admin 用戶進行登錄,由於該用戶同時具有 USER 角色權限,所以登錄後可以訪問 /user/hello 這個接口。
(2)而由於 /db/hello 接口需要 DBA 角色,因此 admin 用戶仍然無法訪問。