最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

jfinal中stateless模式嵌入shiro驗證的實現(xiàn)方式

 更新時間:2022年06月24日 14:26:25   作者:KevinQ  
這篇文章主要介紹了jfinal中stateless模式嵌入shiro驗證,今天,我們就來嘗試一種通過攔截器來實現(xiàn)的Stateless Jfinal嵌入方式,需要的朋友可以參考下

問題起源

在前些天的文章中,我們了解到困惑了我們好幾天的問題是由于jfinal新版中使用undertowServer方式啟動,其嵌入filter的方式有變動,所以導(dǎo)致網(wǎng)上檢索到的通過web.xml嵌入filter失敗。

在不考慮修改undertowServer的情況下,也就意味著我們需要找到一種在undertowServer環(huán)境下,嵌入shiro的方式。

今天,我們就來嘗試一種通過攔截器來實現(xiàn)的Stateless Jfinal 嵌入方式。

Stateless的理解

個人對Stateless的理解就是前后端分離,兩次請求互相獨立,通過約定的token等內(nèi)容判斷是否是同一個用戶。

因此這要求,登錄接口需要給用戶生成一個隨機的token,以便用戶后續(xù)訪問的時候帶上。

登錄接口

登錄接口首先需要我們訪問數(shù)據(jù)庫,以及通過特定算法來驗證用戶名與密碼是否匹配。如果匹配,則生成隨機的字符串,即token,并保存在redis中,注意,映射關(guān)系是token為key,value為用戶信息,可以是用戶名,也可以是用戶id等用戶唯一標(biāo)識。

@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("用戶名與密碼錯誤");
    }
}

另外,需要注意的有兩點:

  • 接口前調(diào)用@Clear,即登錄接口不應(yīng)該被攔截驗證
  • 系統(tǒng)的登錄接口,與shiro中的subject.login應(yīng)該注意區(qū)分,是兩個不同的概念。

自定義攔截器

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("權(quán)限錯誤:", e);
            try {
                throw e;
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
    }
 
    /**
     * 未授權(quán)處理
     *
     * @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,若不為空,將其轉(zhuǎn)換為JWTToken對象,然后調(diào)用shiro的登錄接口:s.login(jwtToken)。

而shiro的login方法會觸發(fā)自定義Realm中的驗證接口:

/**
	 * 自定義認(rèn)證
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
		String token = (String) auth.getCredentials();
		 // 解密獲得username,用于和數(shù)據(jù)庫進(jìn)行對比
        String userName = JwtUtils.getUsername(token);
        if (userName == null || userName == "") {
            throw new AuthenticationException("token 校驗失敗");
        }
		return new SimpleAuthenticationInfo(token, token, getName());
	}

其中,JwtUtils。getUsername的具體代碼如下,和設(shè)置token是對應(yīng)的:

/**
     * @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;
    }

如此,便做到了shiro的嵌入。

遺留問題

目前欠缺的一個問題是,不能實現(xiàn)shiro的注解來進(jìn)行權(quán)限驗證,這個問題我們還準(zhǔn)備借助ShiroPlugin來實現(xiàn),由于jfinal已經(jīng)升級到4.8了,而shiroPlugin目前還停留在支持jfinal 3.x的版本,所以需要我們下載jfianl-shiro-plugin源碼做一些修改。

到此這篇關(guān)于jfinal中stateless模式嵌入shiro驗證的實現(xiàn)方式的文章就介紹到這了,更多相關(guān)jfinal shiro驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot3集成Quartz的示例代碼

    SpringBoot3集成Quartz的示例代碼

    Quartz由Java編寫的功能豐富的開源作業(yè)調(diào)度框架,可以集成到幾乎任何Java應(yīng)用程序中,并且能夠創(chuàng)建多個作業(yè)調(diào)度,在實際的業(yè)務(wù)中,有很多場景依賴定時任務(wù),比如常見的:訂單超時處理,業(yè)務(wù)識別和預(yù)警通知等,本文介紹了SpringBoot3如何集成Quartz
    2023-08-08
  • 完美解決idea突然間很卡的問題

    完美解決idea突然間很卡的問題

    這篇文章主要介紹了完美解決idea突然間很卡的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 關(guān)于MVC的dao層、service層和controller層詳解

    關(guān)于MVC的dao層、service層和controller層詳解

    這篇文章主要介紹了關(guān)于MVC的dao層、service層和controller層詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java實現(xiàn)合并兩個已經(jīng)排序的列表實例代碼

    java實現(xiàn)合并兩個已經(jīng)排序的列表實例代碼

    這篇文章主要介紹了java實現(xiàn)合并兩個已經(jīng)排序的列表實例代碼,有需要的朋友可以參考一下
    2013-12-12
  • java 面向?qū)ο竺嬖嚰\

    java 面向?qū)ο竺嬖嚰\

    這篇文章主要介紹了java 面向?qū)ο竺嬖嚰\的相關(guān)資料,這里整理了面向?qū)ο蟮幕A(chǔ)知識,幫助大家學(xué)習(xí)理解此部分的知識,需要的朋友可以參考下
    2016-11-11
  • java 算法之歸并排序詳解及實現(xiàn)代碼

    java 算法之歸并排序詳解及實現(xiàn)代碼

    這篇文章主要介紹了java 算法之歸并排序詳解及實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java并發(fā)編程示例(一):線程的創(chuàng)建和執(zhí)行

    Java并發(fā)編程示例(一):線程的創(chuàng)建和執(zhí)行

    這篇文章主要介紹了Java并發(fā)編程示例(一):線程的創(chuàng)建和執(zhí)行,本文是系列文章的第一篇,需要的朋友可以參考下
    2014-12-12
  • SpringFramework中的數(shù)據(jù)校驗方式

    SpringFramework中的數(shù)據(jù)校驗方式

    這篇文章主要介紹了SpringFramework中的數(shù)據(jù)校驗方式,本文通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • SpringBoot實現(xiàn)自定義Starter的步驟詳解

    SpringBoot實現(xiàn)自定義Starter的步驟詳解

    在SpringBoot中,Starter是一種特殊的依賴,它可以幫助我們快速地集成一些常用的功能,例如數(shù)據(jù)庫連接、消息隊列、Web框架等。在本文中,我們將介紹如何使用Spring Boot實現(xiàn)自定義Starter,需要的朋友可以參考下
    2023-06-06
  • 基于java中泛型的總結(jié)分析

    基于java中泛型的總結(jié)分析

    本篇文章介紹了,在java中泛型的總結(jié)分析。需要的朋友參考下
    2013-05-05

最新評論

岳普湖县| 大连市| 聊城市| 淅川县| 栾川县| 嘉黎县| 洪洞县| 龙口市| 文成县| 云和县| 贺州市| 永丰县| 景德镇市| 鄄城县| 衡山县| 慈利县| 新密市| 齐齐哈尔市| 临沧市| 巴林左旗| 河南省| 射阳县| 普兰县| 囊谦县| 惠安县| 洪洞县| 乐昌市| 高台县| 阳山县| 临沂市| 林芝县| 邢台市| 扶绥县| 高邑县| 寿宁县| 自治县| 江西省| 蓝山县| 延安市| 保亭| SHOW|