Redian新闻
>
发现一款更轻量级的权限框架,十分钟就能快速上手,yyds

发现一款更轻量级的权限框架,十分钟就能快速上手,yyds

公众号新闻

来源:blog.csdn.net/WayneLee0809/article/details/85702551


前言

作为一名后台开发人员,权限这个名词应该算是特别熟悉的了。就算是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关系不太大,所以版本可以忽略,用你熟悉的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即可,其他地方基本没啥区别。

END

官方站点:www.linuxprobe.com

Linux命令大全:www.linuxcool.com

刘遄老师QQ:5604241

Linux技术交流群:3762708

(新群,火热加群中……)

想要学习Linux系统的读者可以点击"阅读原文"按钮来了解书籍《Linux就该这么学》,同时也非常适合专业的运维人员阅读,成为辅助您工作的高价值工具书!


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
不可操作恍然已经是东京人了圣安德鲁日 | 3分钟快速上手苏格兰常用语!为豆瓣9.3分的动漫,做了一套PPT!YYDS!快来看!中国程序员 YYDS[干货] 《天书奇谭》里这句台词的翻译,yyds!(待会删)yyds的学习资源,请低调使用!无需R语言!0代码15分钟就能复现一篇非肿瘤5+生信!这些改变世界的数学公式,YYDS!比大衣保暖,比羽绒服显瘦!这件高级反貂绒毛衣火了!不起球不掉毛,明明毛茸茸的却巨显瘦,舒适又保暖....YYDS!海蓝之谜yyds!精华、面霜二合一,修复抗老全搞定,半个娱乐圈都在用!佛罗伦萨:夜咖啡,2分钱导游,圣母百花殿复杂场景下的权限系统该怎么玩?ABAC权限模型帮你搞定它!这 30 款 IDEA 宝贝插件 yyds(待会删)yyds,全是付费搞来的,请大家低调浏览!!!手工制作,无添加,十几分钟就能给娃一顿营养早餐,一周不重样毛泽东在延安整风期间说了什么松耦合式的权限控制设计,自定义权限表达式(待会删)yyds,请大家低调浏览!!!一个轻量级的分布式日志标记追踪神器,十分钟接入,非常好用!java更轻量级的权限管理框架:jcasbin这件水貂绒毛衣火了!明明毛茸茸的却还显瘦,舒适又保暖....YYDS!万能通用的Java调优方案合集,yyds!这回稳了,蓝桥杯才是yyds!浦发AE白大焕新,YYDS的高端卡!yyds,付费搞来的,请低调使用!老版画风yyds!萌王的每一件衣服包括睡衣都可爱不行了真香!一个轻量级的日志追踪框架,10 分钟即可接入!(待会删)yyds,想突破英语词汇量的请低调使用!MariaDB 成功上市!MySQL 之父 YYDS!!小众又好看的包包来了!牛皮+非遗侗族手织布,太懂中国女人了,民族的就是yyds!大友克洋yyds!机器人嘉年华!后面yyds,全是付费搞来的资源,请低调使用!性能快如闪电!轻量级 Linux 在 9 年后重出江湖
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。