<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          再見了 Shiro!

          共 13308字,需瀏覽 27分鐘

           ·

          2023-08-31 17:23

          點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)

           國內(nèi)最強(qiáng)微服務(wù)框架,沒有之一!

           幾乎覆蓋 Spring Boot 所有操作!
           2023 全新 Java 面試題(2500+)

          1、前言

          作為一名后臺(tái)開發(fā)人員,權(quán)限這個(gè)名詞應(yīng)該算是特別熟悉的了。就算是java里的類也有 public、private 等“權(quán)限”之分。之前項(xiàng)目里一直使用shiro作為權(quán)限管理的框架。說實(shí)話,shiro的確挺強(qiáng)大的,但是它也有很多不好的地方。shiro默認(rèn)的登錄地址還是login.jsp,前后端分離模式使用shiro還要重寫好多類;手機(jī)端存儲(chǔ)用戶信息、保持登錄狀態(tài)等等,對(duì)shiro來說也是一個(gè)難題。

          在分布式項(xiàng)目里,比如電商項(xiàng)目,其實(shí)不太需要明確的權(quán)限劃分,說白了,我認(rèn)為沒必要做太麻煩的權(quán)限管理,一切從簡(jiǎn)。何況shiro對(duì)于springCloud等各種分布式框架來說,簡(jiǎn)直就是“災(zāi)難”。每個(gè)子系統(tǒng)里都要寫點(diǎn)shiro的東西,慢慢的,越來越惡心。zuul網(wǎng)關(guān)就在這里大顯身手了,控制用戶的登錄,鑒定用戶的權(quán)限等等。zuul網(wǎng)關(guān)控制用戶登錄,鑒權(quán)以后再詳說。以上拙見。

          然后最近我發(fā)現(xiàn)了另一個(gè)權(quán)限框架jcasbin,雖然網(wǎng)上還沒有很多關(guān)于博客,但是我看了一會(huì)就可以使用了。

          github地址:https://github.com/casbin/jcasbin

          2、準(zhǔn)備

          Spring Boot 基礎(chǔ)就不介紹了,推薦看這個(gè)實(shí)戰(zhàn)項(xiàng)目:

          https://github.com/javastacks/spring-boot-best-practice

          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把用戶的角色、權(quán)限信息(訪問路徑)放置在配置文件里,然后通過輸入流讀取配置文件。主要有兩個(gè)配置文件:model.conf 和 policy.csv。簡(jiǎn)單的使用GitHub里都講了,在此就不再贅述了。

          另外,如果你近期準(zhǔn)備面試跳槽,建議在Java面試庫小程序在線刷題,涵蓋 2000+ 道 Java 面試題,幾乎覆蓋了所有主流技術(shù)面試題。

          其實(shí)也可以讀取數(shù)據(jù)庫的角色權(quán)限配置。所以我們可以把關(guān)于數(shù)據(jù)庫的信息提取出來,可以進(jìn)行動(dòng)態(tài)設(shè)置。

          @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里進(jìn)行相關(guān)配置了。model.conf是固定的文件,之間復(fù)制過來放在新建的和src同級(jí)的文件夾下即可。policy.csv的內(nèi)容是可以從數(shù)據(jù)庫讀取的。

          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

          3、讀取權(quán)限信息進(jìn)行初始化

          我們要對(duì)Enforcer這個(gè)類初始化,加載配置文件里的信息。所以我們寫一個(gè)類實(shí)現(xiàn)InitializingBean,在容器加載的時(shí)候就初始化這個(gè)類,方便后續(xù)的使用。

          @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;
              //從數(shù)據(jù)庫讀取策略
              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.
            }
            
            /**
             * 添加權(quán)限
             * @param policy
             * @return
             */
            public static boolean addPolicy(Policy policy){
              boolean addPolicy = enforcer.addPolicy(policy.getSub(),policy.getObj(),policy.getAct());
              enforcer.savePolicy();
              
              return addPolicy;
            }
            
            /**
             * 刪除權(quán)限
             * @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;
            }
            
          }

          在這個(gè)類里,我們注入寫好的配置類,然后轉(zhuǎn)為靜態(tài)的,在afterPropertiesSet方法里實(shí)例化Enforcer并加載policy(策略,角色權(quán)限/url對(duì)應(yīng)關(guān)系)。推薦學(xué)習(xí):Spring Boot 最新學(xué)習(xí)路線圖來了,16 個(gè)模塊,小白都能學(xué)會(huì)!

          同時(shí)又寫了兩個(gè)方法,用來添加和刪除policy,Policy是自定的一個(gè)類,對(duì)官方使用的集合/數(shù)組進(jìn)行了封裝。

          public class Policy {
            /**想要訪問資源的用戶 或者角色*/
            private String sub;
            
            /**將要訪問的資源,可以使用 * 作為通配符,例如/user/* */
            private String obj;
            
            /**用戶對(duì)資源執(zhí)行的操作。HTTP方法,GET、POST、PUT、DELETE等,可以使用 * 作為通配符*/
            private String act;
           
            public Policy() {
              super();
            }
            
            /**
             * 
             * @param sub 想要訪問資源的用戶 或者角色
             * @param obj 將要訪問的資源,可以使用 * 作為通配符,例如/user/*
             * @param act 用戶對(duì)資源執(zhí)行的操作。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 + ];
            }
            
          }

          4、使用

          1、權(quán)限控制

          jcasbin的權(quán)限控制非常簡(jiǎn)單,自定義一個(gè)過濾器,if判斷就可以搞定,沒錯(cuò),就這么簡(jiǎn)單。

          @WebFilter(urlPatterns = /* , filterName = JCasbinAuthzFilter)
          @Order(Ordered.HIGHEST_PRECEDENCE)//執(zhí)行順序,最高級(jí)別最先執(zhí)行,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(無權(quán)訪問);
                Map<String, Object> result = new HashMap<String, Object>();
                      result.put(code, 1001);
                      result.put(msg, 用戶權(quán)限不足);
                      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)這個(gè)方法對(duì)用戶、訪問資源、方式進(jìn)行匹配。這里的邏輯可以根據(jù)自己的業(yè)務(wù)來實(shí)現(xiàn)。在這個(gè)過濾器之前還可以添加一個(gè)判斷用戶是否登錄的過濾器。

          2、添加刪除權(quán)限

          對(duì)于權(quán)限的操作,直接調(diào)用上面寫好的EnforcerFactory里對(duì)應(yīng)的方法即可。并且,可以達(dá)到同步的效果。就是不用重啟服務(wù)器或者其他任何操作,添加或刪除用戶權(quán)限后,用戶對(duì)應(yīng)的訪問就會(huì)收到影響。

          @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();
            }

          5、最后

          其實(shí)可以把jcasbin和SpringCloud的zuul結(jié)合來實(shí)現(xiàn)用戶的統(tǒng)一登錄和權(quán)限控制。自定義一個(gè)過濾器繼承ZuulFilter即可,其他地方基本沒啥區(qū)別。這個(gè)以后再寫。

          版權(quán)聲明:本文為CSDN博主「紅藕香殘玉簟秋」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/WayneLee0809/article/details/85702551


          課程推薦

          技術(shù)更新太快了,現(xiàn)在網(wǎng)上很多都是 Spring Boot 2.0.x、1.5.x 等早期版本的教程,大家盡量不要學(xué)習(xí)過時(shí)的技術(shù)了。

          如果你想系統(tǒng)學(xué)習(xí)全新的 Spring Boot,推薦棧長(zhǎng)的《Spring Boot 核心技術(shù)課,基于全新 3.x 版本幾乎覆蓋 Spring Boot 所有核心知識(shí)點(diǎn),一次付費(fèi),永久學(xué)習(xí)…

          感興趣的掃碼聯(lián)系訂閱學(xué)習(xí):

          ?? 課程詳細(xì)介紹:Spring Boot 核心技術(shù)
          課程原價(jià) 999 元,現(xiàn)在只要 399 元即可上車,想系統(tǒng)學(xué)習(xí) Spring Boot 技術(shù)的盡快上車,不管是用來面試跳槽,還是工作所需,都是相當(dāng)有必要的。

          瀏覽 10948
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产迷奸久久 | 影音先锋女人av资源站 | 亚洲一区二区电影网站 | 亚洲另类在线观看 | 欧美淫秽视频免费看 |