SpringBoot 如何使用 ACL 进行访问控制

news/2025/2/6 1:07:53/

SpringBoot 如何使用 ACL 进行访问控制

在现代 Web 开发中,访问控制是一个非常重要的问题。访问控制可以帮助我们保护敏感信息、防止恶意攻击、维护系统安全等。Spring Security 是一个非常流行的安全框架,它提供了一系列的认证和授权功能,可以帮助我们实现灵活的访问控制。在本文中,我们将介绍如何使用 SpringBoot 和 Spring Security 中的 ACL(Access Control List)来实现访问控制。

在这里插入图片描述

什么是 ACL?

ACL(Access Control List)是一种常见的访问控制机制。ACL 可以控制用户对资源的访问权限。它是一种灵活、可扩展的访问控制机制,可以适应不同的应用场景。

ACL 通常由两个部分组成:访问主体和资源。访问主体可以是用户、角色、组织等,资源可以是文件、数据库表、API 接口等。ACL 可以定义哪些访问主体有权访问哪些资源,并可以设置不同的访问权限,例如读取、修改、删除等。

Spring Security 中的 ACL

Spring Security 是一个基于 Spring 的安全框架,它提供了一系列的认证和授权功能。Spring Security 中的 ACL 可以帮助我们实现灵活的访问控制,它提供了一些基本的 ACL 功能,例如:

  • 定义 ACL 权限
  • 创建和删除 ACL 权限
  • 将 ACL 权限与用户或角色关联
  • 检查用户或角色是否拥有某个 ACL 权限

在 Spring Security 中,ACL 是通过 AclService 和 AclRepository 接口来管理的。AclService 提供了一些基本的 ACL 操作,例如创建 ACL 权限、删除 ACL 权限等。AclRepository 提供了一些查询方法,可以查询 ACL 权限的相关信息。

使用 SpringBoot 和 Spring Security 实现 ACL 访问控制

接下来,我们将介绍如何使用 SpringBoot 和 Spring Security 实现 ACL 访问控制。

准备工作

首先,我们需要准备以下环境:

  • JDK 1.8 或以上版本
  • Maven 3.3 或以上版本
  • SpringBoot 2.5.2 或以上版本
  • MySQL 数据库

创建 SpringBoot 项目

我们可以使用 Spring Initializr 来快速创建一个 SpringBoot 项目。在创建项目时,我们需要添加以下依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-acl</artifactId><version>5.5.1</version>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

这些依赖包含了 Spring Security 和 ACL 相关的组件和依赖。

配置数据库

我们需要配置数据库,以便 SpringBoot 和 Spring Security 可以使用 ACL 来管理访问控制。我们可以在 application.properties 文件中添加以下配置:

spring.datasource.url=jdbc:mysql://localhost:3306/acl_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

这些配置可以让 SpringBoot 自动创建数据库表,并将 ACL 相关的数据存储到数据库中。

创建 ACL 权限

接下来,我们需要创建 ACL 权限。ACL 权限包含以下信息:

  • ObjectIdentity:对象标识符,用于标识资源
  • Sid:安全标识符,用于标识访问主体
  • Permission:权限,用于标识访问权限

我们可以创建一个名为 AclPermission 的实体类,用于表示 ACL 权限:

@Entity
@Table(name = "acl_permission")
public class AclPermission implements Serializable {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@ManyToOne@JoinColumn(name = "object_id_identity")private ObjectIdentity objectIdentity;@ManyToOne@JoinColumn(name = "sid")private Sid sid;@Column(name = "permission")private int permission;// getters and setters
}

在这个实体类中,我们定义了以下属性:

  • id:ACL 权限的唯一标识符
  • objectIdentity:对象标识符,用于标识资源
  • sid:安全标识符,用于标识访问主体
  • permission:权限,用于标识访问权限

创建 ACL 相关的服务

接下来,我们需要创建 ACL 相关的服务。我们可以创建一个名为 AclServiceImpl 的服务来实现 ACL 相关的操作:

@Service
public class AclServiceImpl implements AclService {private final AclRepository aclRepository;public AclServiceImpl(AclRepository aclRepository) {this.aclRepository = aclRepository;}@Overridepublic List<ObjectIdentity> findChildren(ObjectIdentity parentIdentity) {return aclRepository.findChildren(parentIdentity);}@Overridepublic Acl readAclById(ObjectIdentity objectIdentity) throws NotFoundException {return aclRepository.findById(objectIdentity.getIdentifier()).orElseThrow(() -> new NotFoundException("ACL not found"));}@Overridepublic Acl readAclByIdentifier(ObjectIdentity objectIdentity) throws NotFoundException {return aclRepository.findById(objectIdentity.getIdentifier()).orElseThrow(() -> new NotFoundException("ACL not found"));}@Overridepublic Acl createAcl(ObjectIdentity objectIdentity) throws AlreadyExistsException {if (aclRepository.existsById(objectIdentity.getIdentifier())) {throw new AlreadyExistsException("ACL already exists");}Acl acl = new AclImpl(objectIdentity, objectIdentity.getIdentifier(), null,true, new PrincipalSid("admin"), new Date());return aclRepository.save(acl);}@Overridepublic void deleteAcl(ObjectIdentity objectIdentity, boolean deleteChildren) throws NotFoundException {Optional<Acl> aclOptional = aclRepository.findById(objectIdentity.getIdentifier());if (aclOptional.isPresent()) {Acl acl = aclOptional.get();aclRepository.delete(acl);} else {throw new NotFoundException("ACL not found");}}@Overridepublic MutableAcl updateAcl(MutableAcl acl) throws NotFoundException {return aclRepository.save((AclImpl) acl);}@Overridepublic void deleteAcl(ObjectIdentity objectIdentity, boolean deleteChildren, boolean deleteChildrenOnly) throws NotFoundException {throw new NotImplementedException();}
}

在这个服务中,我们实现了 AclService 接口中的方法,包括:

  • findChildren:查询子资源
  • readAclById:根据对象标识符查询 ACL
  • readAclByIdentifier:根据对象标识符查询 ACL
  • createAcl:创建 ACL
  • deleteAcl:删除 ACL
  • updateAcl:更新 ACL

配置 Spring Security

接下来,我们需要配置 Spring Security。我们可以创建一个名为 WebSecurityConfig 的类来配置 Spring Security:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate DataSource dataSource;@Autowiredprivate AclService aclService;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").access("hasRole('ADMIN')").antMatchers("/user/**").access("hasRole('USER')").antMatchers("/public/**").permitAll().anyRequest().authenticated().and().formLogin().and().httpBasic().and().csrf().disable();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.jdbcAuthentication().dataSource(dataSource);}@Beanpublic JdbcMutableAclService jdbcMutableAclService() {return new JdbcMutableAclService(dataSource, new DefaultPermissionGrantingStrategy(), new ConsoleAuditLogger());}@Beanpublic MethodSecurityExpressionHandler methodSecurityExpressionHandler() {DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();expressionHandler.setPermissionEvaluator(new AclPermissionEvaluator(jdbcMutableAclService()));return expressionHandler;}@Beanpublic DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();expressionHandler.setPermissionEvaluator(new AclPermissionEvaluator(jdbcMutableAclService()));return expressionHandler;}@Beanpublic AclPermissionEvaluator aclPermissionEvaluator() {return new AclPermissionEvaluator(jdbcMutableAclService());}@Beanpublic ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy() {return new ObjectIdentityRetrievalStrategy();}@Beanpublic AclAuthorizationStrategy aclAuthorizationStrategy() {return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN"));}@Beanpublic PermissionGrantingStrategy permissionGrantingStrategy() {return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());}@Beanpublic DefaultMethodSecurityMetadataSource methodSecurityMetadataSource() {DefaultMethodSecurityMetadataSource metadataSource = new DefaultMethodSecurityMetadataSource();metadataSource.setExpressionHandler(methodSecurityExpressionHandler());return metadataSource;}@Beanpublic DefaultWebSecurityMetadataSource webSecurityMetadataSource() {DefaultWebSecurityMetadataSource metadataSource = new DefaultWebSecurityMetadataSource();metadataSource.setExpressionHandler(webSecurityExpressionHandler());return metadataSource;}@Beanpublic AclSecurityInterceptor aclSecurityInterceptor() throws Exception {AclSecurityInterceptor interceptor = new AclSecurityInterceptor(jdbcMutableAclService(), objectIdentityRetrievalStrategy(), aclAuthorizationStrategy(), permissionGrantingStrategy());interceptor.setMethodSecurityMetadataSource(methodSecurityMetadataSource());interceptor.setSecurityMetadataSource(webSecurityMetadataSource());interceptor.setAuthenticationManager(authenticationManagerBean());return interceptor;}@Overrideprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}

在这个配置类中,我们完成了以下工作:

  • 配置了访问控制规则,定义了哪些 URL 需要哪些角色才能访问
  • 配置了认证方式,使用了 JDBC 认证
  • 配置了 ACL 相关的组件,包括 MutableAclService、MethodSecurityExpressionHandler 等
  • 配置了 AclSecurityInterceptor,用于处理 ACL 相关的访问控制

创建控制器和视图

最后,我们需要创建控制器和视图来测试 ACL 访问控制。我们可以创建一个名为 DemoController 的控制器:

@RestController
public class DemoController {@GetMapping("/public/hello")public String hello() {return "Hello, public!";}@GetMapping("/user/hello")public String helloUser() {return "Hello, user!";}@GetMapping("/admin/hello")public String helloAdmin() {return "Hello, admin!";}
}

在这个控制器中,我们定义了三个接口,分别对应不同的访问权限。

接下来,我们可以创建相应的视图。我们可以在 resources/templates 目录下创建三个 HTML 文件,分别对应不同的接口:

  • public.html:公共接口
  • user.html:需要 USER 角色才能访问的接口
  • admin.html:需要 ADMIN 角色才能访问的接口

测试 ACL 访问控制

现在,我们可以启动应用程序,并访问三个接口:

  • /public/hello:可以直接访问,不需要权限
  • /user/hello:需要 USER 角色才能访问
  • /admin/hello:需要 ADMIN 角色才能访问

我们可以使用 curl 命令来测试访问控制:

$ curl http://localhost:8080/public/hello
Hello, public!$ curl http://localhost:8080/user/hello
HTTP/1.1 403
Content-Length: 0

这段代码是一个使用 Spring Security 实现 ACL 访问控制的配置类。ACL(Access Control List)访问控制是一种基于资源的访问控制方式,可以控制用户对特定资源的访问权限。

具体来说,这个配置类完成了以下几个方面的工作:

  1. 配置了 HTTP 安全性,包括定义了哪些 URL 需要哪些角色才能访问。
  2. 配置了认证机制,使用 JDBC 认证。
  3. 配置了 ACL 相关的组件,包括 MutableAclService、MethodSecurityExpressionHandler 等。
  4. 配置了 AclSecurityInterceptor,用于实现 ACL 访问控制。

这个配置类的核心是 AclSecurityInterceptor,它是一个 Spring Security 的拦截器,用于在请求到达控制器之前检查用户是否有访问资源的权限。AclSecurityInterceptor 依赖于其他几个组件,包括 MutableAclService、MethodSecurityExpressionHandler 等,这些组件都是为了实现 ACL 访问控制而创建的。

总的来说,这个配置类的作用是实现 ACL 访问控制,确保用户只能访问他们有权限访问的资源。


http://www.ppmy.cn/news/536065.html

相关文章

细粒度分类:Cross-X源码笔记——Cross-X Learning for Fine-Grained Visual Categorization

细粒度分类:Cross-X源码笔记——Cross-X Learning for Fine-Grained Visual Categorization 综述网络结构网络初始化阶段前向传播损失函数模型参数的训练训练初始化阶段训练流程综述 论文题目:《Cross-X Learning for Fine-Grained Visual Categorization》 会议时间:IEEE I…

2021-11-26 ubuntu触摸板和小键盘设置

开机禁用触摸板 使用命令 # 关闭触摸板 sudo modprobe -r psmouse # 打开触摸板 sudo modprobe psmouse可将关闭命令加到开机执行的脚本中 自动禁用&启用触摸板 Touchpad Indicator能够在插入鼠标时自动禁用触摸板&#xff0c;在鼠标移除后重新启用。 在命令终端下运行…

用酒精,湿巾,擦笔记本电脑/键盘,然后触摸板就不能用了?什么情况?

酒精擦笔记本触摸板后&#xff0c;酒精会在触摸板上形成薄膜层&#xff0c;导致使用失灵。用攥干后的湿巾把触摸板擦干净就好了。

Win10 触摸键盘如何开启

最近购买扬创科技X86 7寸工业平板电脑 客户反馈说&#xff0c;你们win10 系统中打开文本自动跳出触摸软件盘是如何设置的&#xff0c;这个功能在哪里开启。界面如下&#xff1a; 此项功能&#xff0c;对于触摸一体机设备来说&#xff0c;非常实用&#xff0c;不需要外接键盘&am…

Win11触摸键盘如何开启?

在Windows11系统中有一个触摸键盘的功能&#xff0c;因此不少能够使用触屏功能的电脑都想要使用这个功能&#xff0c;那么遇到这种情况应该怎么办呢&#xff1f;下面就和小编一起来看看如何开启触摸键盘&#xff0c;希望可以帮助到你呀&#xff01; Win11打开触摸键盘的方法 1、…

【程序员吐槽:公务员月薪3000,为啥比我8000幸福指数还高?】

近年来&#xff0c;随着互联网技术的迅猛发展&#xff0c;程序员成为了社会中备受瞩目的职业之一。虽然工资看似颇丰&#xff0c;但是有不少程序员感叹自己的幸福感却远远低于公务员。这种现象引起了广大程序员的关注和讨论。 我们来看一下公务员的工作环境。公务员身份稳定&a…

Windows电脑关闭触摸键盘的方法

笔记本都会携带触摸键盘&#xff0c;有些用户觉得很好用&#xff0c;也有些用户觉得操作电脑老是会碰到&#xff0c;就想问问有什么关闭的方法吗&#xff1f;那么下面我们就来看看Win10电脑关闭触摸键盘的方法。 番茄花园Win10纯净版下载_番茄花园Win10 64位专业版V2021.08 - …

笔记本(ThinkPad E550c)怎样关闭触摸板 ps:打字时老是容易碰着触摸板

笔记本(ThinkPad E550c)怎样关闭触摸板 ps:打字时老是容易碰着触摸板 首先&#xff0c;下载鲁大师&#xff0c;目的是利用鲁大师的 驱动管理 功能查看并安装或者升级触摸板驱动&#xff0c;别的软件都不好使。 然后 控制面板-》在控制面板中点击硬件和声音选项-》找到设备和打…