這篇文章主要講解了“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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。