在 Spring Boot 2 中集成 JCasbin 并实现 ClassPath 模型文件加载
在 Spring Boot 2 中集成 JCasbin 并实现 ClassPath 模型文件加载
概述
在现代Web应用开发中,权限管理和认证是不可或缺的一部分。JCasbin 是一个强大的、高效的开源访问控制库,它支持多种访问控制模型,并提供了灵活的策略管理机制。本文将介绍如何在 Spring Boot 2 应用程序中集成 JCasbin,并解决加载 classpath 中 model.conf 文件的问题。我们还将探讨 classpath: 和 classpath*: 的异同,以及如何正确地使用它们。
集成步骤
添加依赖
首先,在项目的 pom.xml 文件中添加 JCasbin 的相关依赖:
<!-- https://mvnrepository.com/artifact/org.casbin/jcasbin -->
<dependency>
<groupId>org.casbin</groupId>
<artifactId>jcasbin</artifactId>
<version>1.78.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.casbin/mybatis-adapter -->
<dependency>
<groupId>org.casbin</groupId>
<artifactId>jdbc-adapter</artifactId>
<version>2.10.0</version>
</dependency>
修改 Config 类以支持 ClassPath 加载
为了解决 JCasbin 的 Config 类默认不支持从 Java ClassPath 加载模型配置文件的问题,我们对 org.casbin.jcasbin.config.Config 类进行重写,修改了 parse 方法,使其能够首先尝试从 ClassPath 加载模型文件,如果失败,则回退到文件系统路径。以下是修改后的 parse 方法代码片段:
private void parse(String fname) {
lock.lock();
try {
// 尝试从classpath加载资源
InputStream is = this.getClass().getResourceAsStream(fname);
if (is == null) {
// 如果classpath中没有,则尝试从文件系统加载
try {
is = new FileInputStream(fname);
} catch (Exception e) {
throw new CasbinConfigException("无法找到文件: " + fname, e.getCause());
}
}
BufferedReader buf = new BufferedReader(new InputStreamReader(is));
parseBuffer(buf);
// 确保关闭流
buf.close();
is.close();
} catch (IOException e) {
throw new CasbinConfigException(e.getMessage(), e.getCause());
} finally {
lock.unlock();
}
}
配置 Casbin
接下来,创建一个配置类来初始化 JCasbin 的 Enforcer 实例,该实例会读取权限规则并执行权限检查。:
@Configuration
public class CasbinConfiguration {
@Bean
public Enforcer enforcer(CasbinProperties properties, DataSource dataSource) throws Exception {
JDBCAdapter adapter = new JDBCAdapter(dataSource);
CustomConfig config = new CustomConfig();
config.loadModelFromText(Files.readString(Paths.get(properties.getModelPath())));
Enforcer enforcer = new Enforcer(config, adapter);
enforcer.loadPolicy();
return enforcer;
}
}
请注意,上面的代码片段假设 properties.getModelPath() 返回的是一个可以直接读取文本的文件路径或 ClassPath 资源路径。根据实际情况,可能需要调整这段代码。dataSource使用系统的数据源
处理 ClassPath 资源路径
为了正确加载位于 classpath 下的 model.conf 文件,我们需要理解 classpath: 和 classpath*: 之间的差异。getResourceAsStream() 方法是 Java 原生方法,不支持 classpath*: 语法,这是 Spring 框架特有的功能,用于扫描所有 classpath 下的资源,包括从多个 jar 文件中查找资源。
因此,当您需要通过 Java 原生方法加载资源时,请确保只使用 classpath: 或者直接指定文件路径。对于 Spring 框架提供的工具类,如 ResourceLoader,可以使用 classpath*: 来尝试加载所有匹配的资源。
创建自定义属性类
定义一个配置属性类来接收和设置 application.properties 或 application.yml 中的相关配置。
@Configuration
@ConfigurationProperties(prefix = "casbin")
@Data
public class CasbinProperties {
private String modelPath;
}
实现过滤器进行权限校验
创建一个过滤器,在每次请求到达时,根据用户信息、请求路径和 HTTP 方法调用 Enforcer 进行权限验证。
@Component
@WebFilter(urlPatterns = "/*")
@Order(1)
public class CasbinAuthFilter implements Filter {
private final Enforcer enforcer;
public CasbinAuthFilter(Enforcer enforcer) {
this.enforcer = enforcer;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
UserAccountVo userAccountVo = WebUtil.getCurUserAccountVo(httpRequest);
if (userAccountVo == null){
chain.doFilter(request, response);
return;
}
String user = userAccountVo.getUserId(); // 从请求头获取用户信息
String path = httpRequest.getRequestURI();
String method = httpRequest.getMethod();
// 进行权限校验
if (enforcer.enforce(user, path, method)) {
chain.doFilter(request, response);
} else {
httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
httpResponse.getWriter().write("没有访问权限");
}
}
}
model.conf配置示例
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)
CASBIN_RULE表示例
id,ptype,v0,v1,v2
1,p,1,/*,(GET)|(POST)
结论
通过上述步骤,我们成功地在 Spring Boot 2 应用中集成了 JCasbin,并解决了 model.conf 文件的加载问题。同时,我们也了解了 classpath: 和 classpath*: 之间的区别,并掌握了如何正确地在不同场景下使用它们。这对于任何希望在其应用程序中实现细粒度访问控制的开发者来说都是有价值的知识点。此外,通过重写 Config 类中的 parse 方法,我们实现了更加灵活的模型文件加载机制,使得应用程序更易于部署,特别是在打包为 JAR 文件后部署的情况下。
在 Spring Boot 2 中集成 JCasbin 并实现 ClassPath 模型文件加载的更多相关文章
- Spring Boot 学习系列(09)—自定义Bean的顺序加载
此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Bean 的顺序加载 有些场景中,我们希望编写的Bean能够按照指定的顺序进行加载.比如,有UserServ ...
- 如何在Spring Boot项目中集成微信支付V3
Payment Spring Boot 是微信支付V3的Java实现,仅仅依赖Spring内置的一些类库.配置简单方便,可以让开发者快速为Spring Boot应用接入微信支付. 演示例子: paym ...
- spring boot入门笔记(四) - 多环境配置、加载顺序、静态资源映射
1.多环境配置 先描述下以前的开发流程:从SVN把项目下载到本地,各种修改配置文件,启动成功:完成功能后上传到公司的测试服务器,修改各种配置文件,启动成功:最后到上线的日子里,把新功能中涉及到的文件打 ...
- Spring Boot GraphQL 实战 03_分页、全局异常处理和异步加载
hello,大家好,我是小黑,又和大家见面啦~ 今天我们来继续学习 Spring Boot GraphQL 实战,我们使用的框架是 https://github.com/graphql-java-ki ...
- Spring Cloud Alibaba基础教程:Nacos配置的多文件加载与共享配置
前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式> ...
- WPF 中的 Pack URI地(资源文件加载)
参考资源网http://msdn.microsoft.com/zh-cn/library/aa970069.aspx#Absolute_vs_Relative_Pack_URIs 在 Windows ...
- Spring Boot - Font Awesome OTS parsing error: Failed to convert 字体加载失败
字体文件,加载不出来 解决方案 一 问题是Maven正在过滤字体文件并破坏它们. <resource> <directory>${project.basedir}/src/m ...
- spring boot rest 接口集成 spring security(2) - JWT配置
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- spring boot rest 接口集成 spring security(1) - 最简配置
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- 在Spring Boot项目中使用Spock框架
转载:https://www.jianshu.com/p/f1e354d382cd Spock框架是基于Groovy语言的测试框架,Groovy与Java具备良好的互操作性,因此可以在Spring B ...
随机推荐
- JUC并发—7.AQS源码分析三
大纲 1.等待多线程完成的CountDownLatch介绍 2.CountDownLatch.await()方法源码 3.CountDownLatch.coutDown()方法源码 4.CountDo ...
- ATT&CK实战系列(一)
环境下载 下载靶场环境,并导入虚拟机分别是win2003.win7.winserver2008 配置网络 虚拟机--编辑--虚拟机网络编辑器--添加网络VMnet2--仅主机模式分配的地址是192.1 ...
- Thymeleaf 在页面中直接显示内容
Thymeleaf 在页面中直接显示内容 一般情况下 Thymeleaf 模板要输出变量需要在某个标签中(如<div>.<span>)写th:text等属性来实现.但有时我 ...
- 【Unity】URP中的UGUIShader实现
[Unity]URP 中的 UGUIShader 实现 参考官方 Shader 代码实现: https://github.com/TwoTailsGames/Unity-Built-in-Shader ...
- autMan奥特曼机器人对接新千寻Pro微信框架详细教程
文件下载 1.安装指定版本微信 https://www.123865.com/s/3Wd9-q13jH 2.最新千寻pro下载 [点此网盘下载] 框架教程 1.安装上面的指定微信版本,跟最新的千寻框架 ...
- NebulaGraph Desktop 使用初体验
前言 前两天 NebulaGraph 官方宣布了全新的开源 Desktop,旨在通过一体化方案解决图数据库部署复杂.工具碎片化.学习成本高等的痛点问题,我也是跃跃欲试.前期在初识 NebulaGrap ...
- 使用DeepSeek-R1分析电影票房
最近在学习DeepSeek-R1本地化部署的相关知识,看到了1个比较有意思的视频. 在该视频中,其主要逻辑就是当用户上传1个Excel后,之后就可以通过交互式的方式对这个Excel中的数据进行分析.但 ...
- 面试题30. 包含min函数的栈
地址:https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/ <?php /** 定义栈的数据结构,请在该类型中实现一 ...
- php的token管理类(AI生成)
当然,以下是一个简单的 PHP 类,用于生成和管理令牌(token).这个类可以生成一个随机的令牌.验证令牌是否有效,并允许设置一个令牌的过期时间. <?php class Token { pr ...
- ITSS 运维2.0 实践
最近公司在评审itss 2.0,参与了一部分工作,对工作过程中的问题梳理如下: 大的背景:评审itss 2.0会有评审 为什么公司会申请各种资质 首次申请资质后,公司可以申请一笔费用(x万元)! 申请 ...