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

SpringSecurity+jwt+captcha登錄認(rèn)證授權(quán)流程總結(jié)

 更新時(shí)間:2024年11月15日 14:27:08   作者:慢生活的人。  
本文介紹了SpringSecurity、JWT和驗(yàn)證碼在Spring Boot 3.2.0中的應(yīng)用,包括登錄認(rèn)證和授權(quán)流程的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

SpringSecurity+jwt+captcha登錄認(rèn)證授權(quán)總結(jié)

版本信息:

springboot 3.2.0、springSecurity 6.2.0、mybatis-plus 3.5.5

認(rèn)證授權(quán)思路和流程: 未攜帶token,訪問(wèn)登錄接口:

1、用戶登錄攜帶賬號(hào)密碼

2、請(qǐng)求到達(dá)自定義Filter,自定義Filter(如JwtAuthenticationTokenFilter)繼承OncePerRequestFilter(此Filter只會(huì)進(jìn)行一次過(guò)濾,在請(qǐng)求返回時(shí),不會(huì)再進(jìn)行調(diào)用),在SecurityConfig中配置,將自定義Filter添加到過(guò)濾器鏈中并加在UsernamePasswordAuthenticationFilter過(guò)濾器之前

3、自定義Filter邏輯

3.1、查詢到用戶未攜帶token,直接放行,進(jìn)入到后面認(rèn)證流程

3.2、將用戶信息封裝成Authentication對(duì)象,調(diào)用authticate()方法進(jìn)行驗(yàn)證,一直到DaoAuthenticationProvider中,會(huì)調(diào)用UserDetailService的loadUserByUserName()方法;自定義UserDetailServiceImpl繼承UserDetailService接口;重寫其loadUserByUserName()方法;查到用戶后,封裝成UserDetail對(duì)象返回

4、調(diào)用passwordEncoder的驗(yàn)證方法進(jìn)行用戶信息的認(rèn)證(一般使用BCryptPasswordEncoder,創(chuàng)建此Bean并放入容器中)

5、認(rèn)證通過(guò)后,使用JWT創(chuàng)建token并放到redis中;返回token到前端

攜帶token訪問(wèn):

1、請(qǐng)求到達(dá)自定義Filter中,獲取token,先驗(yàn)證token的正確性,從token中獲取到userId,根據(jù)userId從redis中獲取用戶信息,將用戶信息封裝成Authentication對(duì)象,放進(jìn)SecurityContextHolder中,后面的過(guò)濾器會(huì)在SecurityContextHolder中獲取用戶的信息

2、請(qǐng)求到達(dá)FilterSecurityInterceptor,在springSecurity中默認(rèn)使用FilterSecurityInterceptor來(lái)進(jìn)行權(quán)限校驗(yàn);FilterSecurityInterceptor會(huì)從SecurityContextHolder中獲取Authentication,然后獲取其中的權(quán)限信息,判斷當(dāng)前用戶是否擁有當(dāng)前資源的訪問(wèn)權(quán)限;

3、通過(guò)權(quán)限判斷,獲取資源返回給前端;

登錄認(rèn)證流程圖:

基于RBAC的授權(quán)控制: RBAC概念:

Role-Based Access Control,中文意思是:基于角色(Role)的訪問(wèn)控制。這是一種廣泛應(yīng)用于計(jì)算機(jī)系統(tǒng)和網(wǎng)絡(luò)安全領(lǐng)域的訪問(wèn)控制模型。

簡(jiǎn)單來(lái)說(shuō),就是通過(guò)將權(quán)限分配給角色,再將角色分配給用戶,來(lái)實(shí)現(xiàn)對(duì)系統(tǒng)資源的訪問(wèn)控制。一個(gè)用戶擁有若干角色,每一個(gè)角色擁有若干權(quán)限。這樣,就構(gòu)造成“用戶-角色-權(quán)限”的授權(quán)模型。在這種模型中,用戶與角色之間,角色與權(quán)限之間,一般是多對(duì)多的關(guān)系

模型:

在數(shù)據(jù)庫(kù)中主要體現(xiàn)用戶表、角色表菜單表、用戶角色關(guān)聯(lián)表角色菜單關(guān)聯(lián)表五個(gè)模型:

CREATE TABLE "mySchema"."t_user"
(
"id" INT IDENTITY(1, 1) NOT NULL,
"username" VARCHAR(100) NOT NULL,
"password" VARCHAR(100) NOT NULL,
"email" VARCHAR(100) NOT NULL,
"phone" VARCHAR(100),
UNIQUE("id"),
UNIQUE("username"),
UNIQUE("email"),
UNIQUE("phone"),
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "mySchema"."t_user" IS '用戶表';
COMMENT ON COLUMN "mySchema"."t_user"."id" IS '用戶id';
COMMENT ON COLUMN "mySchema"."t_user"."username" IS '用戶名';
COMMENT ON COLUMN "mySchema"."t_user"."password" IS '密碼';
COMMENT ON COLUMN "mySchema"."t_user"."email" IS '用戶郵箱';
COMMENT ON COLUMN "mySchema"."t_user"."phone" IS '電話';
CREATE TABLE "mySchema"."sys_role"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL,
"name" VARCHAR(128) DEFAULT NULL,
"role_key" VARCHAR(100) DEFAULT NULL,
"status" CHAR(1) DEFAULT '0',
"del_flag" INT DEFAULT 0,
"create_by" BIGINT DEFAULT NULL,
"create_time" DATETIME(6) DEFAULT NULL,
"update_by" BIGINT DEFAULT NULL,
"update_time" DATETIME(6) DEFAULT NULL,
"remark" VARCHAR(500) DEFAULT NULL,
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "mySchema"."sys_role" IS '角色表';
COMMENT ON COLUMN "mySchema"."sys_role"."id" IS '角色id';
COMMENT ON COLUMN "mySchema"."sys_role"."name" IS '角色名稱';
COMMENT ON COLUMN "mySchema"."sys_role"."role_key" IS '角色權(quán)限字符串';
COMMENT ON COLUMN "mySchema"."sys_role"."status" IS '角色狀態(tài)(0正常, 1停用)';
COMMENT ON COLUMN "mySchema"."sys_role"."del_flag" IS '刪除標(biāo)志(0未刪除,1已刪除)';
COMMENT ON COLUMN "mySchema"."sys_role"."remark" IS '備注';
CREATE TABLE "mySchema"."sys_menu"
(
"id" BIGINT IDENTITY(2, 1) NOT NULL,
"menu_name" VARCHAR(64) DEFAULT 'NULL' NOT NULL,
"path" VARCHAR(200) DEFAULT NULL,
"component" VARCHAR(50) DEFAULT NULL,
"visible" CHAR(1) DEFAULT '0',
"status" CHAR(1) DEFAULT '0',
"perms" VARCHAR(100) DEFAULT NULL,
"icon" VARCHAR(100) DEFAULT '#',
"create_by" BIGINT DEFAULT NULL,
"create_time" DATETIME(6) DEFAULT CURRENT_TIMESTAMP,
"update_by" BIGINT DEFAULT NULL,
"update_time" DATETIME(6) DEFAULT CURRENT_TIMESTAMP,
"delete_f1ag" INT DEFAULT 0,
"remark" VARCHAR(500) DEFAULT NULL,
UNIQUE("id"),
NOT CLUSTER PRIMARY KEY("id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "mySchema"."sys_menu" IS '菜單表';
COMMENT ON COLUMN "mySchema"."sys_menu"."menu_name" IS '菜單名';
COMMENT ON COLUMN "mySchema"."sys_menu"."path" IS '路由地址';
COMMENT ON COLUMN "mySchema"."sys_menu"."component" IS '組件路徑';
COMMENT ON COLUMN "mySchema"."sys_menu"."visible" IS '菜單狀態(tài)(0顯示1隱藏)';
COMMENT ON COLUMN "mySchema"."sys_menu"."status" IS '菜單狀態(tài)(0正常1停用)';
COMMENT ON COLUMN "mySchema"."sys_menu"."perms" IS '權(quán)限標(biāo)識(shí)';
COMMENT ON COLUMN "mySchema"."sys_menu"."icon" IS '菜單圖標(biāo)';
COMMENT ON COLUMN "mySchema"."sys_menu"."delete_f1ag" IS '是否刪除(0未刪除1已刪除)';
COMMENT ON COLUMN "mySchema"."sys_menu"."remark" IS '備注';
CREATE TABLE "mySchema"."sys_user_role"
(
"user_id" BIGINT DEFAULT 0 NOT NULL,
"role_id" BIGINT DEFAULT 0 NOT NULL,
NOT CLUSTER PRIMARY KEY("user_id", "role_id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "mySchema"."sys_user_role" IS '用戶角色表';
COMMENT ON COLUMN "mySchema"."sys_user_role"."user_id" IS '用戶id';
COMMENT ON COLUMN "mySchema"."sys_user_role"."role_id" IS '角色id';
CREATE TABLE "mySchema"."sys_role_menu"
(
"role_id" BIGINT DEFAULT 0 NOT NULL,
"menu_id" BIGINT DEFAULT 0 NOT NULL,
NOT CLUSTER PRIMARY KEY("role_id", "menu_id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "mySchema"."sys_role_menu" IS '角色菜單關(guān)聯(lián)表';
COMMENT ON COLUMN "mySchema"."sys_role_menu"."role_id" IS '角色id';
COMMENT ON COLUMN "mySchema"."sys_role_menu"."menu_id" IS '菜單id';

權(quán)限流程:

用戶表、角色表、菜單表、部門表、用戶角色關(guān)聯(lián)表、角色菜單關(guān)聯(lián)表;數(shù)據(jù)權(quán)限分為5種:個(gè)人、全部、本部門、指定部門、本部門及以下
鏈路:

1、用戶注冊(cè),指定部門;創(chuàng)建角色,給角色賦菜單權(quán)限、數(shù)據(jù)權(quán)限;給用戶賦予角色;
2、用戶登錄,通過(guò)用戶的所有角色,獲取所有的菜單權(quán)限和最大數(shù)據(jù)權(quán)限;菜單數(shù)據(jù)直接展示在頁(yè)面;所有數(shù)據(jù)都有創(chuàng)建人,則數(shù)據(jù)的部門id是創(chuàng)建人的部門id;
3、在訪問(wèn)數(shù)據(jù)接口時(shí),通過(guò)mybatis的攔截器對(duì)用戶的數(shù)據(jù)進(jìn)行過(guò)濾(拼接sql),返回給前端;

captcha圖片驗(yàn)證碼:

實(shí)現(xiàn)思路:

1、圖片驗(yàn)證碼獲取,并將驗(yàn)證碼驗(yàn)證碼存放起來(lái)(單機(jī)應(yīng)用可放在session中,分布式應(yīng)用放在redis中)

2、當(dāng)用戶登錄時(shí),攜帶驗(yàn)證碼以及驗(yàn)證碼的key,進(jìn)入到后端從redis中獲取值進(jìn)行驗(yàn)證

<!-- 谷歌kaptcha驗(yàn)證碼依賴 -->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

代碼思路:

1、生成驗(yàn)證碼

public Result<CaptchaVO> getCaptcha() throws IOException {
    // 生成文字驗(yàn)證碼
    String content = defaultKaptcha.createText();
    // 生成圖片驗(yàn)證碼
    ByteArrayOutputStream outputStream = null;
    BufferedImage image = defaultKaptcha.createImage(content);
    outputStream = new ByteArrayOutputStream();
    ImageIO.write(image, "jpg", outputStream);
    // 對(duì)字節(jié)數(shù)組Base64編碼
    String str = "data:image/jpeg;base64,";
    String base64Img = str + Base64.getEncoder().encodeToString(outputStream.toByteArray()).replace("\n", "").replace("\r", "");
    CaptchaVO captchaVO = captchaService.cacheCaptcha(content);
    captchaVO.setBase64Img(base64Img);
    return Result.success(captchaVO);
}

2、存儲(chǔ)驗(yàn)證碼

@Service
public class CaptchaService {
    private Long timeout = 300L;
    @Autowired
    private RedisUtils redisUtils;
    private final String CAPTCHA_KEY_PREFIX = "captcha:verification:";
    public CaptchaVO cacheCaptcha(String captcha){
        //生成一個(gè)隨機(jī)標(biāo)識(shí)符
        String randomStr = UUID.randomUUID().toString();
        //緩存驗(yàn)證碼并設(shè)置過(guò)期時(shí)間
        String captchaKey = CAPTCHA_KEY_PREFIX.concat(randomStr);
        redisUtils.set(captchaKey, captcha, timeout, TimeUnit.SECONDS);
        CaptchaVO captchaVO = new CaptchaVO();
        captchaVO.setCaptchaKey(captchaKey);
        captchaVO.setExpire(timeout);
        captchaVO.setCaptcha(captcha);
        return captchaVO;
    }
}

3、校驗(yàn)驗(yàn)證碼

Object captcha = redisUtils.get(reqVO.getCaptchaKey());
if (Objects.isNull(captcha)) {
    return "驗(yàn)證碼已過(guò)期";
}
if (!captcha.equals(reqVO.getCaptcha())) {
    return "驗(yàn)證碼錯(cuò)誤";
}

到此這篇關(guān)于SpringSecurity+jwt+captcha登錄認(rèn)證授權(quán)總結(jié)的文章就介紹到這了,更多相關(guān)SpringSecurity jwt captcha認(rèn)證授權(quán)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java使用組件編寫窗口實(shí)現(xiàn)網(wǎng)上文件下載

    Java使用組件編寫窗口實(shí)現(xiàn)網(wǎng)上文件下載

    這篇文章主要為大家詳細(xì)介紹了Java使用組件編寫窗口實(shí)現(xiàn)網(wǎng)上文件下載的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Java中如何檢查數(shù)組是否包含某整數(shù)

    Java中如何檢查數(shù)組是否包含某整數(shù)

    這篇文章主要介紹了在?Java?中檢查數(shù)組是否包含某整數(shù),在本文中,我們使用了幾個(gè)內(nèi)置的方法,如anyMatch()、contains()、binarySearch()等,我們將在給定的數(shù)組中找到一個(gè)值,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Java基礎(chǔ)之匿名內(nèi)部類、包裝類

    Java基礎(chǔ)之匿名內(nèi)部類、包裝類

    這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • SpringMVC框架使用jackson封裝數(shù)據(jù)過(guò)程中遇到的問(wèn)題及解決

    SpringMVC框架使用jackson封裝數(shù)據(jù)過(guò)程中遇到的問(wèn)題及解決

    這篇文章主要介紹了SpringMVC框架使用jackson封裝數(shù)據(jù)過(guò)程中遇到的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java數(shù)據(jù)結(jié)構(gòu)篇之實(shí)現(xiàn)二叉搜索樹的核心方法

    Java數(shù)據(jù)結(jié)構(gòu)篇之實(shí)現(xiàn)二叉搜索樹的核心方法

    二叉搜索樹是一種常用的數(shù)據(jù)結(jié)構(gòu),它是一棵二叉樹,且每個(gè)節(jié)點(diǎn)的值都大于其左子樹中任何節(jié)點(diǎn)的值,而小于其右子樹中任何節(jié)點(diǎn)的值,這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)結(jié)構(gòu)篇之實(shí)現(xiàn)二叉搜索樹的核心方法,需要的朋友可以參考下
    2023-12-12
  • java多態(tài)的向上轉(zhuǎn)型的概念及實(shí)例分析

    java多態(tài)的向上轉(zhuǎn)型的概念及實(shí)例分析

    在本篇內(nèi)容里小編給大家整理的是一篇關(guān)于java多態(tài)的向上轉(zhuǎn)型的概念及實(shí)例分析,對(duì)此有興趣的朋友們可以跟著學(xué)習(xí)下。
    2021-05-05
  • Idea如何查看Maven依賴樹

    Idea如何查看Maven依賴樹

    這篇文章主要介紹了Idea如何查看Maven依賴樹問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Java線程等待用法實(shí)例分析

    Java線程等待用法實(shí)例分析

    這篇文章主要介紹了Java線程等待用法,結(jié)合實(shí)例形式分析了obj.wait()實(shí)現(xiàn)線程等待相關(guān)原理與操作技巧,需要的朋友可以參考下
    2018-09-09
  • java字符串相加時(shí)的內(nèi)存表現(xiàn)和原理分析

    java字符串相加時(shí)的內(nèi)存表現(xiàn)和原理分析

    這篇文章主要介紹了java字符串相加時(shí)的內(nèi)存表現(xiàn)和原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java連接zookeeper的3種方式小結(jié)

    java連接zookeeper的3種方式小結(jié)

    這篇文章主要介紹了java連接zookeeper的3種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評(píng)論

清河县| 那曲县| 清河县| 康马县| 无极县| 沧州市| 昆山市| 鸡西市| 桓台县| 邻水| 呼和浩特市| 辽源市| 永吉县| 喜德县| 太白县| 南宁市| 项城市| 盐池县| 兴山县| 岳普湖县| 长乐市| 历史| 吕梁市| 辽阳市| 广丰县| 金塔县| 河间市| 合作市| 大宁县| 威海市| 辽宁省| 乐安县| 鹰潭市| 蕉岭县| 青神县| 彭州市| 兴业县| 文成县| 那坡县| 佛坪县| 孟连|