您好,登錄后才能下訂單哦!
這篇文章主要講解了“jfinal中stateless模式怎么嵌入shiro驗證”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“jfinal中stateless模式怎么嵌入shiro驗證”吧!
個人對Stateless的理解就是前后端分離,兩次請求互相獨立,通過約定的token等內容判斷是否是同一個用戶。
因此這要求,登錄接口需要給用戶生成一個隨機的token,以便用戶后續訪問的時候帶上。
登錄接口首先需要我們訪問數據庫,以及通過特定算法來驗證用戶名與密碼是否匹配。如果匹配,則生成隨機的字符串,即token,并保存在redis中,注意,映射關系是token為key,value為用戶信息,可以是用戶名,也可以是用戶id等用戶唯一標識。
@Clear public void Login() { String name = getPara("name"); String password = getPara("password"); if ("admin".equals(name)) { // TODO 判斷密碼與用戶名是否正確 Cache cache = Redis.use(); String token = StrKit.getRandomUUID(); cache.set("TOKEN:" + token, name); renderText(token); } else { renderText("用戶名與密碼錯誤"); } }
另外,需要注意的有兩點:
接口前調用@Clear,即登錄接口不應該被攔截驗證
系統的登錄接口,與shiro中的subject.login應該注意區分,是兩個不同的概念。
package com.holdoa.core.interceptor; import com.holdoa.core.controller.BaseController; import com.holdoa.core.filter.JWTToken; import com.jfinal.aop.Interceptor; import com.jfinal.aop.Invocation; import com.jfinal.core.Controller; import com.jfinal.kit.LogKit; import com.jfinal.kit.StrKit; import org.apache.shiro.SecurityUtils; import org.apache.shiro.aop.MethodInvocation; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.aop.AnnotationsAuthorizingMethodInterceptor; import org.apache.shiro.subject.Subject; import java.lang.reflect.Method; public class MyShiroInterceptor extends AnnotationsAuthorizingMethodInterceptor implements Interceptor { public MyShiroInterceptor() { getMethodInterceptors(); } public void intercept(final Invocation inv) { try { String token = inv.getController().getHeader("token"); if (StrKit.isBlank(token)) { BaseController b = (BaseController) inv.getController(); b.renderAppError("缺少token"); return; } else { Subject s = SecurityUtils.getSubject(); JWTToken jwtToken = new JWTToken(token); s.login(jwtToken); inv.invoke(); } } catch (Throwable e) { if (e instanceof AuthorizationException) { doProcessuUnauthorization(inv.getController()); } LogKit.warn("權限錯誤:", e); try { throw e; } catch (Throwable throwable) { throwable.printStackTrace(); } } } /** * 未授權處理 * * @param controller controller */ private void doProcessuUnauthorization(Controller controller) { controller.redirect("/login/noLogin"); } }
上面的代碼很長,我們重點看其中的這幾行:
String token = inv.getController().getHeader("token"); if (StrKit.isBlank(token)) { BaseController b = (BaseController) inv.getController(); b.renderAppError("缺少token"); return; } else { Subject s = SecurityUtils.getSubject(); JWTToken jwtToken = new JWTToken(token); s.login(jwtToken); inv.invoke(); }
邏輯可以描述為:獲取token,若不為空,將其轉換為JWTToken對象,然后調用shiro的登錄接口:s.login(jwtToken)
。
而shiro的login方法會觸發自定義Realm中的驗證接口:
/** * 自定義認證 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException { String token = (String) auth.getCredentials(); // 解密獲得username,用于和數據庫進行對比 String userName = JwtUtils.getUsername(token); if (userName == null || userName == "") { throw new AuthenticationException("token 校驗失敗"); } return new SimpleAuthenticationInfo(token, token, getName()); }
其中,JwtUtils。getUsername的具體代碼如下,和設置token是對應的:
/** * @return token中包含的用戶名 */ public static String getUsername(String token) { Cache cache = Redis.use(); String username = (String)cache.get(RedisKeyPreFix.NEW_OA_MANAGE_TOKEN_PREFIX + token); return username; }
感謝各位的閱讀,以上就是“jfinal中stateless模式怎么嵌入shiro驗證”的內容了,經過本文的學習后,相信大家對jfinal中stateless模式怎么嵌入shiro驗證這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。