開源項目Jfinal-shiro-jwt:shiro驗證失敗跳轉位置代碼優先還是配置優先

      網友投稿 979 2022-05-30

      尋覓

      最近幾天一直在尋找jfinal+shiro的結合方式,特別是適配自定義的token驗證方式,自然是希望能找到已經開源的項目,其次再說自我實現代碼。

      關于shiro

      官方地址:https://shiro.apache.org/

      有些文檔還是需要讀一讀的:

      官方文檔:https://shiro.apache.org/documentation.html

      infoQ介紹文章:https://www.infoq.com/articles/apache-shiro/

      jfinal-shiro-jwt

      jwt,JSON WEB TOKEN驗證,目前我們使用該種方式進行身份驗證。另外在框架管理系統發展中,希望能嵌入后端的權限管理,所以最近看上了shiro。所以一直在尋覓jfinal+shiro的最佳組合方式。

      前些天看了看jfinal-shiro-plugins,是使用-來實現的。

      同事發現網上有一個jfinal-shiro-jwt的項目,或許對實現權限管理有所幫助,因此來學習研究一番。

      項目地址:https://github.com/perfree/Jfinal-shiro-jwt

      保險起見,我把它復制了一份在gitee中:https://gitee.com/wieweicoding/Jfinal-shiro-jwt

      clone到本地:

      git clone https://gitee.com/wieweicoding/Jfinal-shiro-jwt

      然后使用IDE打開項目,等待編譯完成。目錄結果如下圖所示:

      除jfinal常規的Controller,程序入口以及配置外,shiro相關的類包括:ShiroDbRealm,ShiroInterceptor,JWTFilter。token轉換相關的類包括JWTToken,JwtUtils。

      TestController中有三個接口,如下:

      package com.perfree.controller; import java.util.Date; import java.util.HashMap; import java.util.Map; import com.jfinal.core.Controller; import com.perfree.common.AjaxResult; import com.perfree.jwt.JwtUtils; import org.apache.shiro.authz.annotation.RequiresRoles; /** * 測試Controller * @author Perfree */ public class TestController extends Controller{ /** * 首頁 */ public void index() { renderText("這是首頁"); } /** * 登錄頁 */ public void login() { renderText("請登錄"); } /** * 登錄操作 */ public void doLogin() { try { String name = getPara("name"); String password = getPara("password"); if(name.equals("perfree") && password.equals("123456")) { Map map = new HashMap<>(); map.put("name", name); renderJson(new AjaxResult(AjaxResult.SUCCESS, JwtUtils.createJwt(map, new Date(System.currentTimeMillis()+360000)))); }else { renderJson(new AjaxResult(AjaxResult.ERROR,"用戶名或密碼錯誤")); } } catch (Exception e) { renderJson(new AjaxResult(AjaxResult.FAILD,"系統異常")); } } }

      我們看一下shiro.ini的文件內容:

      [main] #realm 自定義realm shiroDbRealm=com.perfree.shiro.ShiroDbRealm securityManager.realms = $shiroDbRealm sessionManager=org.apache.shiro.session.mgt.DefaultSessionManager securityManager.sessionManager=$sessionManager securityManager.sessionManager.sessionValidationSchedulerEnabled = false # 退出跳轉路徑 logout.redirectUrl = /login [filters] app_authc = com.perfree.jwt.JWTFilter app_authc.loginUrl = /login # 登錄成功跳轉路徑 可以自己定義 app_authc.successUrl = /index #路徑角色權限設置 [urls] /login = anon /doLogin = anon /resources/** = anon /logout = logout /** = app_authc,roles[admin]

      這里我們說一下路徑角色權限設置的含義:

      開源項目Jfinal-shiro-jwt:shiro驗證失敗跳轉位置代碼優先還是配置優先

      anon:表示無需認證即可訪問,即允許匿名訪問。

      authc:需要認證才可訪問。

      user:點擊“記住我”功能可訪問。

      其實這些含義表示這些訪問路徑指定了過濾器,如anon表示指定了過濾器為AnonymousFilter。

      同樣的,app_authc也對應了在配置文件上半部分配置的過濾器:

      [filters] app_authc = com.perfree.jwt.JWTFilter app_authc.loginUrl = /login # 登錄成功跳轉路徑 可以自己定義 app_authc.successUrl = /index

      運行測試

      我們將項目運行起來,程序入口為com.perfree.Main.class

      首先,我們嘗試訪問/index接口,如下圖為postman訪問測試:

      接口沒有返回預期的內容,而是返回了“請登錄”三個字,這似乎是下面login接口的返回內容,這是怎么一回事呢?

      我們可以從配置行/** = app_authc,roles[admin]得到一些啟發。而其對應的配置中有app_authc.loginUrl = /login,那么是否跟這個有關呢?

      再讓我們看一下這個過濾器的具體內容:

      package com.perfree.jwt; import java.io.IOException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; /** * 自定義Shiro的過濾器 * @author Perfree * */ public class JWTFilter extends BasicHttpAuthenticationFilter { /** * 判斷用戶是否想要登入。 * 檢測header里面是否包含authc字段即可 */ @Override protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) { HttpServletRequest req = (HttpServletRequest) request; String authorization = req.getHeader("authc"); return authorization != null; } /** * 如果攜帶token進行登錄 */ @Override protected boolean executeLogin(ServletRequest request, ServletResponse response){ HttpServletRequest httpServletRequest = (HttpServletRequest) request; String authorization = httpServletRequest.getHeader("authc"); JWTToken token = new JWTToken(authorization); // 提交給realm進行登入,如果錯誤他會拋出異常并被捕獲 getSubject(request, response).login(token); // 如果沒有拋出異常則代表登入成功,返回true return true; } @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { HttpServletResponse resp = (HttpServletResponse)response; Boolean flag = true; //判斷用戶是否攜帶了token if (isLoginAttempt(request, response)) { try { executeLogin(request, response); } catch (Exception e) { flag = false; } if(!flag) { try { resp.sendRedirect("/login"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return flag; }else { //未攜帶token,重定向至登錄頁面 try { resp.sendRedirect("/login"); } catch (IOException e1) { } return false; } } }

      我們看到有幾行代碼中有:

      resp.sendRedirect("/login");

      到底是配置文件在其作用,還是該重定向代碼呢?

      我們先打斷點看看:

      首先,確實是執行到了具體重定向語句,我們嘗試修改該語句,再來測試一下:

      將/login修改為/noLogin,其接口內容如下:

      public void noLogin() { renderText("未登錄測試!"); }

      重新測試:

      首先,我們發現,該過濾器會一直自我循環中,猜測是因為配置文件中配置的/**=app_authc導致重定向/noLogin也會走該過濾器的問題,所以我們在ini中配置:

      /noLogin = anon

      再次測試:

      由此可見,配置與代碼不一時,代碼是要優先于配置設置的。

      統一身份認證服務 IAM

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:關于Python數據分析的入門指南
      下一篇:【Python3網絡爬蟲開發實戰】1.2.6-aiohttp的安裝
      相關文章
      亚洲av日韩av无码av| 亚洲综合图片小说区热久久| 亚洲一级毛片在线观| 亚洲视频在线观看免费视频| 亚洲国产AV无码专区亚洲AV| 亚洲色精品vr一区二区三区| 日日噜噜噜噜夜夜爽亚洲精品| 久久亚洲国产精品五月天婷| 中文字幕亚洲不卡在线亚瑟| 国产亚洲大尺度无码无码专线| 中文字幕专区在线亚洲| 伊伊人成亚洲综合人网7777| 亚洲一区二区三区自拍公司| 亚洲一区精品无码| 久久精品亚洲一区二区| 亚洲va在线va天堂va888www| 亚洲综合国产精品| 亚洲国产一区二区三区| 久久久亚洲精品无码| 亚洲精品午夜无码电影网| a级亚洲片精品久久久久久久 | 亚洲AV无码精品色午夜在线观看| 亚洲日韩精品A∨片无码| 亚洲AV中文无码字幕色三| 亚洲AV日韩精品久久久久久| 亚洲AV日韩AV永久无码免下载| 亚洲国产成人久久综合碰碰动漫3d | 在线观看国产一区亚洲bd| 亚洲成人高清在线| 国产亚洲精品成人a v小说| 亚洲三区在线观看无套内射| 亚洲AV无码久久| 亚洲国产综合在线| 亚洲日韩一区二区一无码| 色婷婷亚洲一区二区三区| 亚洲色图综合在线| 国产精品亚洲а∨无码播放 | 豆国产96在线|亚洲| 亚洲国产一区二区三区| 亚洲国产精品无码久久久秋霞2| 亚洲性天天干天天摸|