龙空技术网

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

老诚不bug 3606

前言:

此刻小伙伴们对“java访问权限大小关系”大体比较重视,我们都想要了解一些“java访问权限大小关系”的相关资讯。那么小编在网络上收集了一些有关“java访问权限大小关系””的相关资讯,希望看官们能喜欢,朋友们快快来学习一下吧!

前言

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

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

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

顺手贴上github地址:

一、准备

基于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.confpolicy.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=falseorg.jcasbin.driver-class-name=com.mysql.jdbc.Driverorg.jcasbin.username=rootorg.jcasbin.password=rootorg.jcasbin.model-path=conf/authz_model.conf
二、读取权限信息进行初始化

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

@Componentpublic 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即可,其他地方基本没啥区别。

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

标签: #java访问权限大小关系