Spring Boot 提供了多种权限管理方式,以下是几种常见的方法,以及相应的示例:
在基于角色的访问控制中,权限分配给角色,然后将角色分配给用户。这种方法简化了权限管理,因为您只需要管理角色和用户之间的关系。
示例:使用 Spring Security 实现 RBAC
1.1. 添加 Spring Security 依赖项到 pom.xml
:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
1.2. 创建一个 SecurityConfig
类,继承 WebSecurityConfigurerAdapter
,并配置角色和权限:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
.antMatchers("/").permitAll()
.and().formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("admin123")).roles("ADMIN")
.and()
.withUser("user").password(passwordEncoder().encode("user123")).roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
在基于属性的访问控制中,权限是基于用户、资源和环境属性的。这种方法提供了更细粒度的权限控制,但可能更难管理。
示例:使用 Spring Security 的 @PreAuthorize
实现 ABAC
2.1. 在 SecurityConfig
类中启用方法安全性:
@EnableGlobalMethodSecurity(prePostEnabled = true)
2.2. 在需要保护的方法上添加 @PreAuthorize
注解:
@RestController
@RequestMapping("/api")
public class ApiController {
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin")
public String admin() {
return "Admin area";
}
@PreAuthorize("hasRole('USER')")
@GetMapping("/user")
public String user() {
return "User area";
}
}
在基于访问控制列表的权限管理中,为每个资源定义一个访问控制列表,指定哪些用户或角色可以访问该资源。这种方法适用于需要对每个资源进行细粒度控制的场景。
示例:使用 Spring Security 的 ACL 模块实现 ACL
3.1. 添加 Spring Security ACL 依赖项到 pom.xml
:
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-aclartifactId>
<version>5.6.1version>
dependency>
3.2. 配置 ACL 数据源、服务和权限评估器:
@Configuration
public class AclConfig {
@Autowired
private DataSource dataSource;
@Bean
public JdbcMutableAclService aclService() {
return new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache());
}
@Bean
public AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
@Bean
public PermissionGrantingStrategy permissionGrantingStrategy() {
return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());
}
@Bean
public EhCacheBasedAclCache aclCache() {
return new EhCacheBasedAclCache(ehCacheFactoryBean().getObject(), permissionGrantingStrategy(), aclAuthorizationStrategy());
}
@Bean
public EhCacheFactoryBean ehCacheFactoryBean() {
EhCacheFactoryBean factoryBean = new EhCacheFactoryBean();
factoryBean.setCacheManager(cacheManager().getObject());
factoryBean.setCacheName("aclCache");
return factoryBean;
}
@Bean
public EhCacheManagerFactoryBean cacheManager() {
return new EhCacheManagerFactoryBean();
}
@Bean
public LookupStrategy lookupStrategy() {
return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger());
}
@Bean
public AclPermissionEvaluator permissionEvaluator() {
return new AclPermissionEvaluator(aclService());
}
}
3.3. 在需要保护的方法上添加 @PreAuthorize
注解,使用 hasPermission
表达式:
@PreAuthorize("hasPermission(#resourceId, 'com.example.Resource', 'read')")
@GetMapping("/resource/{resourceId}")
public String getResource(@PathVariable Long resourceId) {
return "Resource " + resourceId;
}
这些示例仅用于演示 Spring Boot 中权限管理的几种方式。实际应用中,您可能需要根据项目需求进行更详细的配置和实现。