springboot整合jcasbin权限管理

 更新时间:2023年09月27日 09:38:26   作者:红藕香残玉簟秋  
jcasbin的权限控制非常简单,本文就来介绍一下springboot整合jcasbin权限管理,具有一定的参考价值,感兴趣的可以了解一下

前言

作为一名后台开发人员,权限这个名词应该算是特别熟悉的了。就算是java里的类也有 public、private 等“权限”之分。之前项目里一直使用shiro作为权限管理的框架。说实话,shiro的确挺强大的,但是它也有很多不好的地方。shiro默认的登录地址还是login.jsp,前后端分离模式使用shiro还要重写好多类;手机端存储用户信息、保持登录状态等等,对shiro来说也是一个难题。

在分布式项目里,比如电商项目,其实不太需要明确的权限划分,说白了,我认为没必要做太麻烦的权限管理,一切从简。何况shiro对于springCloud等各种分布式框架来说,简直就是“灾难”。每个子系统里都要写点shiro的东西,慢慢的,越来越恶心。zuul网关就在这里大显身手了,控制用户的登录,鉴定用户的权限等等。zuul网关控制用户登录,鉴权以后再详说。以上拙见。

然后最近我发现了另一个权限框架jcasbin,虽然网上还没有很多关于博客,但是我看了一会就可以使用了。

顺手贴上github地址:https://github.com/casbin/jcasbin

一、准备

基于springboot1.5.10,但是和springboot关系不太大。

1、mavan仓库引入

       <dependency>
            <groupId>org.casbin</groupId>
            <artifactId>jcasbin</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.casbin</groupId>
            <artifactId>jdbc-adapter</artifactId>
            <version>1.1.0</version>
        </dependency>

2、配置文件

jcasbin把用户的角色、权限信息(访问路径)放置在配置文件里,然后通过输入流读取配置文件。主要有两个配置文件:model.conf 和 policy.csv。简单的使用GitHub里都讲了,在此就不再赘述了。

其实也可以读取数据库的角色权限配置。所以我们可以把关于数据库的信息提取出来,可以进行动态设置。

@Configuration
@ConfigurationProperties(prefix = "org.jcasbin")
public class EnforcerConfigProperties {
	private String url;
	private String driverClassName;
	private String username;
	private String password;
	private String modelPath;
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public String getDriverClassName() {
		return driverClassName;
	}
	public void setDriverClassName(String driverClassName) {
		this.driverClassName = driverClassName;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getModelPath() {
		return modelPath;
	}
	public void setModelPath(String modelPath) {
		this.modelPath = modelPath;
	}
	@Override
	public String toString() {
		return "EnforcerConfigProperties [url=" + url + ", driverClassName=" + driverClassName + ", username="
				+ username + ", password=" + password + ", modelPath=" + modelPath + "]";
	}
}

这样我们就可以在application.properties里进行相关配置了。model.conf是固定的文件,之间复制过来放在新建的和src同级的文件夹下即可。policy.csv的内容是可以从数据库读取的。

org.jcasbin.url=jdbc:mysql://localhost:3306/casbin?useSSL=false
org.jcasbin.driver-class-name=com.mysql.jdbc.Driver
org.jcasbin.username=root
org.jcasbin.password=root
org.jcasbin.model-path=conf/authz_model.conf

二、读取权限信息进行初始化

我们要对Enforcer这个类初始化,加载配置文件里的信息。所以我们写一个类实现InitializingBean,在容器加载的时候就初始化这个类,方便后续的使用。

@Component
public class EnforcerFactory implements InitializingBean {
	private static Enforcer enforcer;
	@Autowired
	private EnforcerConfigProperties enforcerConfigProperties;
	private static EnforcerConfigProperties config;
	@Override
	public void afterPropertiesSet() throws Exception {
		config = enforcerConfigProperties;
		//从数据库读取策略
		JDBCAdapter jdbcAdapter = new JDBCAdapter(config.getDriverClassName(),config.getUrl(),config.getUsername(),
													config.getPassword(), true);
		enforcer = new Enforcer(config.getModelPath(), jdbcAdapter);
		enforcer.loadPolicy();//Load the policy from DB.
	}
	/**
	 * 添加权限
	 * @param policy
	 * @return
	 */
	public static boolean addPolicy(Policy policy){
		boolean addPolicy = enforcer.addPolicy(policy.getSub(),policy.getObj(),policy.getAct());
		enforcer.savePolicy();
		return addPolicy;
	}
	/**
	 * 删除权限
	 * @param policy
	 * @return
	 */
	public static boolean removePolicy(Policy policy){
		boolean removePolicy = enforcer.removePolicy(policy.getSub(),policy.getObj(),policy.getAct());
		enforcer.savePolicy();
		return removePolicy;
	}
	public static Enforcer getEnforcer(){
		return enforcer;
	}
}

在这个类里,我们注入写好的配置类,然后转为静态的,在afterPropertiesSet方法里实例化Enforcer并加载policy(策略,角色权限/url对应关系)。

同时又写了两个方法,用来添加和删除policy,Policy是自定的一个类,对官方使用的集合/数组进行了封装。

public class Policy {
	/**想要访问资源的用户 或者角色*/
	private String sub;
	/**将要访问的资源,可以使用  * 作为通配符,例如/user/* */
	private String obj;
	/**用户对资源执行的操作。HTTP方法,GET、POST、PUT、DELETE等,可以使用 * 作为通配符*/
	private String act;
	public Policy() {
		super();
	}
	/**
	 * 
	 * @param sub 想要访问资源的用户 或者角色
	 * @param obj 将要访问的资源,可以使用  * 作为通配符,例如/user/*
	 * @param act 用户对资源执行的操作。HTTP方法,GET、POST、PUT、DELETE等,可以使用 * 作为通配符
	 */
	public Policy(String sub, String obj, String act) {
		super();
		this.sub = sub;
		this.obj = obj;
		this.act = act;
	}
	public String getSub() {
		return sub;
	}
	public void setSub(String sub) {
		this.sub = sub;
	}
	public String getObj() {
		return obj;
	}
	public void setObj(String obj) {
		this.obj = obj;
	}
	public String getAct() {
		return act;
	}
	public void setAct(String act) {
		this.act = act;
	}
	@Override
	public String toString() {
		return "Policy [sub=" + sub + ", obj=" + obj + ", act=" + act + "]";
	}
}

三、使用

1、权限控制

jcasbin的权限控制非常简单,自定义一个过滤器,if判断就可以搞定,没错,就这么简单。

@WebFilter(urlPatterns = "/*" , filterName = "JCasbinAuthzFilter")
@Order(Ordered.HIGHEST_PRECEDENCE)//执行顺序,最高级别最先执行,int从小到大
public class JCasbinAuthzFilter implements Filter {
	private static final Logger log = LoggerFactory.getLogger(JCasbinAuthzFilter.class);
	private static Enforcer enforcer;
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String user = request.getParameter("username");
        String path = request.getRequestURI();
        String method = request.getMethod();
        enforcer = EnforcerFactory.getEnforcer();
        if (path.contains("anon")) {
        	chain.doFilter(request, response);
		}else if (enforcer.enforce(user, path, method)) {
			chain.doFilter(request, response);
		} else {
			log.info("无权访问");
			Map<String, Object> result = new HashMap<String, Object>();
            result.put("code", 1001);
            result.put("msg", "用户权限不足");
            result.put("data",null);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().write(JSONObject.toJSONString(result,SerializerFeature.WriteMapNullValue));
	    }
	}
	@Override
	public void destroy() {
	}
}

主要是用enforcer.enforce(user, path, method)这个方法对用户、访问资源、方式进行匹配。这里的逻辑可以根据自己的业务来实现。在这个过滤器之前还可以添加一个判断用户是否登录的过滤器。

2、添加删除权限

对于权限的操作,直接调用上面写好的EnforcerFactory里对应的方法即可。并且,可以达到同步的效果。就是不用重启服务器或者其他任何操作,添加或删除用户权限后,用户对应的访问就会收到影响。

@PutMapping("/anon/role/per")
	public ResultBO<Object> addPer(){
		EnforcerFactory.addPolicy(new Policy("alice", "/user/list", "*"));
		return ResultTool.success();
	}
	@DeleteMapping("/anon/role/per")
	public ResultBO<Object> deletePer(){
		EnforcerFactory.removePolicy(new Policy("alice", "/user/list", "*"));
		return ResultTool.success();
	}

写在后面的话

其实可以把jcasbin和SpringCloud的zuul结合来实现用户的统一登录和权限控制。自定义一个过滤器继承ZuulFilter即可,其他地方基本没啥区别。这个以后再写。

到此这篇关于springboot整合jcasbin权限管理的文章就介绍到这了,更多相关springboot jcasbin权限内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot统一返回格式的方法详解

    SpringBoot统一返回格式的方法详解

    今天小编主要是和大家分享一个让代码变得更简洁的小技巧:统一返回格式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-08-08
  • java实现一个简单的网络爬虫代码示例

    java实现一个简单的网络爬虫代码示例

    这篇文章主要介绍了java实现一个简单的网络爬虫代码示例,还是挺不错的,这里分享给大家,需要的朋友可以参考下。
    2017-11-11
  • Java微信公众号推送模版消息的步骤示例详解

    Java微信公众号推送模版消息的步骤示例详解

    模板消息是一种向用户发送通知的服务,广泛用于订单状态更新、服务提醒等场景,下面,我将详细介绍如何使用Java结合微信官方提供的API来实现模板消息的推送,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • Java开发之ssm三大框架整合

    Java开发之ssm三大框架整合

    SSM框架是spring MVC ,spring和mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层,使用spring MVC负责请求的转发和视图管理,spring实现业务对象管理,mybatis作为数据对象的持久化引擎
    2022-05-05
  • 探讨Java验证码制作(下篇)

    探讨Java验证码制作(下篇)

    这篇文章主要介绍了探讨Java验证码制作(下篇)的相关资料,需要的朋友可以参考下
    2016-05-05
  • Springboot 整合 Java DL4J 实现农产品质量检测系统(推荐)

    Springboot 整合 Java DL4J 实现农产品质量检测系统(推荐)

    本文详细介绍了系统的搭建过程,包括技术选型、数据处理、模型训练和评估等关键步骤,系统采用卷积神经网络,对水果成熟度和缺陷进行识别,有效解决了传统方法成本高、效率低的问题,有助于提升农产品检测的科技含量和自动化水平
    2024-10-10
  • 基于java中子类的继承性的应用介绍

    基于java中子类的继承性的应用介绍

    本篇介绍了,基于java中子类的继承性的应用。需要的朋友参考下
    2013-05-05
  • Java中的递归方法示例介绍

    Java中的递归方法示例介绍

    大家好,本篇文章主要讲的是Java中的递归方法示例介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • springboot websocket集群(stomp协议)连接时候传递参数

    springboot websocket集群(stomp协议)连接时候传递参数

    这篇文章主要介绍了springboot websocket集群(stomp协议)连接时候传递参数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • ZooKeeper Java API编程实例分析

    ZooKeeper Java API编程实例分析

    本文主要通过实例给大家详细分析了ZooKeeper用JAVA实现API编程的知识要点。
    2017-11-11

最新评论