在 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.propertiesapplication.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 模型文件加载的更多相关文章

  1. Spring Boot 学习系列(09)—自定义Bean的顺序加载

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Bean 的顺序加载 有些场景中,我们希望编写的Bean能够按照指定的顺序进行加载.比如,有UserServ ...

  2. 如何在Spring Boot项目中集成微信支付V3

    Payment Spring Boot 是微信支付V3的Java实现,仅仅依赖Spring内置的一些类库.配置简单方便,可以让开发者快速为Spring Boot应用接入微信支付. 演示例子: paym ...

  3. spring boot入门笔记(四) - 多环境配置、加载顺序、静态资源映射

    1.多环境配置 先描述下以前的开发流程:从SVN把项目下载到本地,各种修改配置文件,启动成功:完成功能后上传到公司的测试服务器,修改各种配置文件,启动成功:最后到上线的日子里,把新功能中涉及到的文件打 ...

  4. Spring Boot GraphQL 实战 03_分页、全局异常处理和异步加载

    hello,大家好,我是小黑,又和大家见面啦~ 今天我们来继续学习 Spring Boot GraphQL 实战,我们使用的框架是 https://github.com/graphql-java-ki ...

  5. Spring Cloud Alibaba基础教程:Nacos配置的多文件加载与共享配置

    前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式> ...

  6. WPF 中的 Pack URI地(资源文件加载)

    参考资源网http://msdn.microsoft.com/zh-cn/library/aa970069.aspx#Absolute_vs_Relative_Pack_URIs 在 Windows ...

  7. Spring Boot - Font Awesome OTS parsing error: Failed to convert 字体加载失败

    字体文件,加载不出来 解决方案  一 问题是Maven正在过滤字体文件并破坏它们. <resource> <directory>${project.basedir}/src/m ...

  8. spring boot rest 接口集成 spring security(2) - JWT配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  9. spring boot rest 接口集成 spring security(1) - 最简配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  10. 在Spring Boot项目中使用Spock框架

    转载:https://www.jianshu.com/p/f1e354d382cd Spock框架是基于Groovy语言的测试框架,Groovy与Java具备良好的互操作性,因此可以在Spring B ...

随机推荐

  1. Windows11本地部署DeepSeek加速

    技术背景 在上一篇文章中我们介绍了在Ubuntu Linux操作系统上部署了一个DeepSeek-R1:14B,再通过其他电脑远程调用模型进行生成的方法.这里我们介绍一下Windows11安装Olla ...

  2. Luogu P1784 数独 [ 模板 ] / P1074 靶形数独 题解 [ 蓝 ] [ 深搜 ] [ 剪枝 ] [ 卡常 ]

    数独模板 , 靶形数独 卡了 2h ,再也不想写数独了. 普通数独 思路 显然是对每个格子进行枚举,类似八皇后的方法去做,朴素方法是由 \((1,1)\) 到 \((9,9)\) 遍历过去. 优化 我 ...

  3. kickstart和PXE安装

    Kickstart安装Kickstart是一种无人值守的安装方式如果在安装过程中出现要填写参数的情况,安装程序首先会去查找Kickstart生成的文件,如果找到合适的参数,就采用所找到的参数:如果没有 ...

  4. DeepSeek本地性能调优

    技术背景 大模型性能调优是一个很复杂的工程,涉及到很多细节,如果真要对模型动刀子,还需要对模型和数据集本身有非常好的理解.这里我们仅仅考虑模型加载过程中,可以优化的一些参数配置.关于DeepSeek在 ...

  5. Thymeleaf Split

    <th:block th:each="image : ${#strings.listSplit(goods.images, ';')}"> <img th:src ...

  6. Ansible - [07] 定义变量的几种方式

    题记部分 Ansible 支持十几种定义变量的方式 Inventory 变量 Host Facts 变量 Register 变量 Playbook 变量 Playbook 提示变量 变量文件 命令行变 ...

  7. 实验一:Tableau数据可视化入门

    实验目的: 1.熟悉TableauDesktop使用方法. 2.通过Tableau软件来实现Excel中数据的基本可视化. 实验原理: Tableau是新一代商业智能工具软件,它将数据连接.运算.分析 ...

  8. 利用Windows自带性能计数器分析软件产品的性能瓶颈(转)

    利用Windows性能计数器分析软件产品的性能瓶颈转自:http://blog.163.com/jack_test/blog/static/166620663201061594459936/ [摘要] ...

  9. 开源!Django-Vue3-Admin的Python后台管理系统

    Django-Vue3-Admin 项目简介 Django-Vue3-Admin 是一个基于 Django + Vue3 的前后端分离的后台管理系统,采用了最新的前后端技术栈,内置了丰富的功能模块,可 ...

  10. BUUCTF---Morse

    1.题目 -..../.----/-..../-..../-..../...--/--.../....-/-..../-..../--.../-.../...--/.----/--.../...--/ ...