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

SpringSecurity實(shí)現(xiàn)自定義數(shù)據(jù)源實(shí)戰(zhàn)指南

 更新時(shí)間:2025年09月10日 09:36:46   作者:?X?  
本文給大家介紹SpringSecurity實(shí)現(xiàn)自定義數(shù)據(jù)源的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

Spring Security簡(jiǎn)介

Java中的安全框架通常是指解決Web應(yīng)用安全問(wèn)題的框架。自行實(shí)現(xiàn)Web應(yīng)用的安全性并不容易,需要考慮不同的認(rèn)證和授權(quán)機(jī)制、網(wǎng)絡(luò)關(guān)鍵數(shù)據(jù)傳輸加密等多方面的問(wèn)題。
Java中常用的安全框架有Spring Security和Shiro,這兩個(gè)安全框架都提供了強(qiáng)大功能,可以很容易實(shí)現(xiàn)Web應(yīng)用的很多安全防護(hù)。下面對(duì)這兩個(gè)安全框架的特點(diǎn)進(jìn)行講解
Spring Security是Spring生態(tài)系統(tǒng)中重要的一員,是一個(gè)基于AOP思想和Servlet過(guò)濾器實(shí)現(xiàn)的安全框架,它提供了完善的認(rèn)證機(jī)制和方法級(jí)的授權(quán)功能,是一款非常優(yōu)秀的權(quán)限管理框架。

在進(jìn)行安全管理的過(guò)程中都涉及權(quán)限管理的兩個(gè)重要概念:Authentication(認(rèn)證)
和Authorization(授權(quán))。權(quán)限管理是指根據(jù)系統(tǒng)設(shè)置的安全規(guī)則或者安全策略,用戶可以訪問(wèn)且只能訪問(wèn)自己被授權(quán)的資源。
實(shí)現(xiàn)權(quán)限管理通常需要三個(gè)對(duì)象,分別為用戶、角色、權(quán)限,這三個(gè)對(duì)象的說(shuō)明如下。

  • 用戶:主要包含用戶名、密碼和當(dāng)前用戶的角色信息,可以實(shí)現(xiàn)認(rèn)證操作。
  • 角色:主要包含角色名稱、角色描述和當(dāng)前角色擁有的權(quán)限信息,可以實(shí)現(xiàn)授權(quán)操作。
  • 權(quán)限:權(quán)限也可以稱為菜單,主要包含當(dāng)前權(quán)限名稱、url地址等信息,可以實(shí)現(xiàn)動(dòng)態(tài)展示菜單。

一、SQL數(shù)據(jù)表的設(shè)計(jì)

-- 創(chuàng)建用戶表
CREATE TABLE `user` (
  -- 主鍵id,自增
  `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '用戶id',
  -- 用戶名字段
  `username` VARCHAR(32) DEFAULT NULL COMMENT '用戶名',
  -- 密碼字段(建議存儲(chǔ)加密后的密碼)
  `password` VARCHAR(255) DEFAULT NULL COMMENT '密碼',
  -- 賬戶啟用狀態(tài):1=啟用,0=禁用
  `enabled` TINYINT(1) DEFAULT NULL COMMENT '是否可用',
  -- 賬戶未過(guò)期標(biāo)志:1=未過(guò)期,0=已過(guò)期
  `accountNonExpired` TINYINT(1) DEFAULT NULL COMMENT '賬戶過(guò)期',
  -- 賬戶未鎖定標(biāo)志:1=未鎖定,0=已鎖定  
  `accountNonLocked` TINYINT(1) DEFAULT NULL COMMENT '賬戶鎖定',
  -- 憑證未過(guò)期標(biāo)志:1=未過(guò)期,0=已過(guò)期
  `credentialsNonExpired` TINYINT(1) DEFAULT NULL COMMENT '憑證過(guò)期',
  -- 設(shè)置主鍵
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 創(chuàng)建角色表(使用roles避免與MySQL關(guān)鍵字沖突)
CREATE TABLE `roles` (
  -- 主鍵id,自增
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  -- 角色英文名,如ROLE_ADMIN
  `name` VARCHAR(32) DEFAULT NULL,
  -- 角色中文名,如管理員
  `name_zh` VARCHAR(32) DEFAULT NULL,
  -- 設(shè)置主鍵
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 創(chuàng)建用戶角色關(guān)聯(lián)表(多對(duì)多關(guān)系)
CREATE TABLE `user_role` (
  -- 主鍵id,自增
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  -- 用戶id,關(guān)聯(lián)user表
  `uid` INT(11) DEFAULT NULL,
  -- 角色id,關(guān)聯(lián)roles表
  `rid` INT(11) DEFAULT NULL,
  -- 設(shè)置主鍵
  PRIMARY KEY (`id`),
  -- 為uid字段創(chuàng)建索引,提高查詢效率
  KEY `uid` (`uid`),
  -- 為rid字段創(chuàng)建索引,提高查詢效率
  KEY `rid` (`rid`),
  -- 外鍵約束:uid引用user表的id字段
  CONSTRAINT `user_role_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user` (`id`),
  -- 外鍵約束:rid引用roles表的id字段
  CONSTRAINT `user_role_ibfk_2` FOREIGN KEY (`rid`) REFERENCES `roles` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
-- ==================== 第一步:插入用戶數(shù)據(jù) ====================
-- 插入3個(gè)測(cè)試用戶
INSERT INTO `user` (
    `username`, 
    `password`, 
    `enabled`, 
    `accountNonExpired`, 
    `accountNonLocked`, 
    `credentialsNonExpired`
) VALUES 
-- 管理員用戶:全部狀態(tài)正常
('admin', 'admin123', 1, 1, 1, 1),
-- 普通用戶:正常可用
('zhangsan', '123456', 1, 1, 1, 1),
-- 被禁用的用戶:用于測(cè)試禁用功能
('lisi', '123456', 0, 1, 1, 1);
-- ==================== 第二步:插入角色數(shù)據(jù) ====================
-- 插入幾個(gè)常用角色
INSERT INTO `roles` (`name`, `name_zh`) VALUES 
('ROLE_ADMIN', '管理員'),
('ROLE_USER', '普通用戶'),
('ROLE_GUEST', '訪客');
-- ==================== 第三步:插入用戶角色關(guān)聯(lián) ====================
-- 給用戶分配角色
INSERT INTO `user_role` (`uid`, `rid`) VALUES 
-- admin用戶:同時(shí)擁有管理員和普通用戶角色
(1, 1),  -- admin -> ROLE_ADMIN
(1, 2),  -- admin -> ROLE_USER
-- zhangsan用戶:只有普通用戶角色
(2, 2),  -- zhangsan -> ROLE_USER
-- lisi用戶:只有訪客角色
(3, 3);  -- lisi -> ROLE_GUEST

二、引入Maven依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

三、配置yml文件

spring:
  application:
    name: SpringSecurity
  datasource:
    url: jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: com.example.springsecurity.mapper/**/*.xml

四、編寫實(shí)體類、mapper.xml、mapper層

package com.example.springsecurity.entity;
import lombok.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Roles {
    private Integer id;
    private String name;
    private String nameZh;
}
package com.example.springsecurity.entity;
import lombok.ToString;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.*;
@ToString
// 自定義用戶User
public class User implements UserDetails {/*這里繼承UserDetails是因?yàn)镾pringSecurity低層只認(rèn)這個(gè),相當(dāng)于不良人只認(rèn)大帥不認(rèn)令牌*/
    private Integer id; // 用戶id
    private String username;    // 用戶名
    private String password;    // 密碼
    private boolean enabled;    // 是否可用
    private boolean accountNonExpired;  // 賬戶過(guò)期
    private boolean accountNonLocked;   // 賬戶鎖定
    private boolean credentialsNonExpired;  // 憑證過(guò)期
    private List<Roles> roles = new ArrayList<>();   // 用戶角色信息
    // 返回權(quán)限信息
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Set<SimpleGrantedAuthority> authorities = new HashSet<>();
        roles.forEach(role -> {
            SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(role.getName());
            authorities.add(simpleGrantedAuthority);
        });
        return authorities;
    }
    @Override
    public String getPassword() {
        return password;
    }
    @Override
    public String getUsername() {
        return username;
    }
    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }
    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }
    @Override
    public boolean isEnabled() {
        return enabled;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
    public void setAccountNonExpired(boolean accountNonExpired) {
        this.accountNonExpired = accountNonExpired;
    }
    public void setAccountNonLocked(boolean accountNonLocked) {
        this.accountNonLocked = accountNonLocked;
    }
    public void setCredentialsNonExpired(boolean credentialsNonExpired) {
        this.credentialsNonExpired = credentialsNonExpired;
    }
    public void setRoles(List<Roles> roles) {
        this.roles = roles;
    }
    public Integer getId() {
        return id;
    }
    public List<Roles> getRoles() {
        return roles;
    }
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springsecurity.mapper.RolesMapper">
    <select id="queryRolesByName" resultType="com.example.springsecurity.entity.Roles">
            select
                r.id,
                r.name,
                r.name_zh
            from
                roles r,user_role `ur`
            where
                r.id = `ur`.rid
              and
                ur.uid = #{uid}
    </select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springsecurity.mapper.UserMapper">
    <select id="queryUserByName" resultType="com.example.springsecurity.entity.User">
        select * from user <if test="username !=null and username !=''">
        <where>
            username = #{username}
        </where>
         limit  1
    </if>
    </select>
</mapper>
public interface RolesMapper {
    List<Roles> queryRolesByName(@Param("uid") Integer uid);
}
public interface UserMapper {
    User queryUserByName(@Param("username") String username);
}

五、編寫service層

@Service
@RequiredArgsConstructor//lombok自動(dòng)生成構(gòu)造函數(shù)
public class MyDetailsService  implements UserDetailsService {
    private final UserMapper userMapper;
    private final RolesMapper rolesMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("username:========"+username);
        User user = userMapper.queryUserByName(username);
        if(ObjectUtil.isEmpty(user))
        {
            throw new UsernameNotFoundException("用戶不存在");
        }
        //這里因?yàn)闆](méi)有配置密碼格式,后臺(tái)數(shù)據(jù)庫(kù)如果是明文的話,就需要用這個(gè)暫時(shí)“過(guò)渡”一下
        user.setPassword("{noop}" + user.getPassword());
        List<Roles> roles = rolesMapper.queryRolesByName(user.getId());
        user.setRoles(roles);
        return user;
    }
}

六、測(cè)試運(yùn)行

到此這篇關(guān)于SpringSecurity實(shí)現(xiàn)自定義數(shù)據(jù)源的文章就介紹到這了,更多相關(guān)SpringSecurity自定義數(shù)據(jù)源內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文詳解jvm中的引用類型

    一文詳解jvm中的引用類型

    在Java中對(duì)象以引用來(lái)指向JVM的內(nèi)存區(qū)塊,這里我們總結(jié)了強(qiáng)引用、軟引用、弱引用和假象引用(幽靈引用),下面這篇文章主要給大家介紹了關(guān)于jvm中引用類型的相關(guān)資料,需要的朋友可以參考下
    2024-04-04
  • 已有的springcloud+mybatis項(xiàng)目升級(jí)為mybatis-plus的方法

    已有的springcloud+mybatis項(xiàng)目升級(jí)為mybatis-plus的方法

    這篇文章主要介紹了已有的springcloud+mybatis項(xiàng)目升級(jí)為mybatis-plus,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java實(shí)現(xiàn)前端jsencrypt.js加密后端解密的示例代碼

    Java實(shí)現(xiàn)前端jsencrypt.js加密后端解密的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用jsencrypt.js實(shí)現(xiàn)前端加密,利用Java實(shí)現(xiàn)后端解密的功能,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-09-09
  • Java使用POI-TL實(shí)現(xiàn)生成有個(gè)性的簡(jiǎn)歷

    Java使用POI-TL實(shí)現(xiàn)生成有個(gè)性的簡(jiǎn)歷

    POI-TL?是一個(gè)基于?Apache?POI?的?Java?庫(kù),專注于在?Microsoft?Word?文檔(.docx?格式)中進(jìn)行模板填充和動(dòng)態(tài)內(nèi)容生成,下面我們看看如何使用POI-TL生成有個(gè)性的簡(jiǎn)歷吧
    2024-11-11
  • 淺析Java?NIO?直接緩沖區(qū)和非直接緩沖區(qū)

    淺析Java?NIO?直接緩沖區(qū)和非直接緩沖區(qū)

    本篇文章主要為大家介紹了Java?NIO?中直接緩沖區(qū)和非直接緩沖區(qū)的定義以及使用流程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • IDEA 集成log4j將SQL語(yǔ)句打印在控制臺(tái)上的實(shí)現(xiàn)操作

    IDEA 集成log4j將SQL語(yǔ)句打印在控制臺(tái)上的實(shí)現(xiàn)操作

    這篇文章主要介紹了IDEA 集成log4j將SQL語(yǔ)句打印在控制臺(tái)上的實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • Mybatis 的 Interceptor(攔截器) 與 JSqlparser 結(jié)合解析SQL 使SpringBoot項(xiàng)目多數(shù)據(jù)庫(kù)兼容的嘗試(推薦)

    Mybatis 的 Interceptor(攔截器) 與 JSqlparser&

    MyBatis插件提供了在SQL執(zhí)行前進(jìn)行攔截、擴(kuò)展的功能,允許用戶自定義邏輯處理,本文介紹Mybatis 的 Interceptor(攔截器) 與 JSqlparser 結(jié)合解析SQL 使SpringBoot項(xiàng)目多數(shù)據(jù)庫(kù)兼容的嘗試(推薦),感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Dubbo無(wú)法訪問(wèn)遠(yuǎn)程Zookeeper已注冊(cè)服務(wù)的問(wèn)題解決方案

    Dubbo無(wú)法訪問(wèn)遠(yuǎn)程Zookeeper已注冊(cè)服務(wù)的問(wèn)題解決方案

    今天小編就為大家分享一篇關(guān)于Dubbo無(wú)法訪問(wèn)遠(yuǎn)程Zookeeper已注冊(cè)服務(wù)的問(wèn)題解決方案,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • Spring組件實(shí)例化擴(kuò)展點(diǎn)之InstantiationAwareBeanPostProcessor使用場(chǎng)景解析

    Spring組件實(shí)例化擴(kuò)展點(diǎn)之InstantiationAwareBeanPostProcessor使用場(chǎng)景解析

    InstantiationAwareBeanPostProcessor是Spring 生命周期中的一個(gè)關(guān)鍵擴(kuò)展接口,繼承自 BeanPostProcessor,這篇文章主要介紹了Spring組件實(shí)例化擴(kuò)展點(diǎn)之InstantiationAwareBeanPostProcessor使用場(chǎng)景解析,需要的朋友可以參考下
    2025-06-06
  • 在idea中全局引入并運(yùn)行ElementUI方式

    在idea中全局引入并運(yùn)行ElementUI方式

    本文詳細(xì)描述了如何在IDEA中使用ElementUI,包括從官網(wǎng)獲取連接、在IDEA終端運(yùn)行命令安裝ElementUI,以及如何在項(xiàng)目中全局引入ElementUI,通過(guò)新建頁(yè)面并配置index.js和ElementUI.vue,可以實(shí)現(xiàn)在本地服務(wù)器上的展示
    2024-10-10

最新評(píng)論

龙井市| 安阳县| 邯郸市| 台中市| 洱源县| 秦皇岛市| 乌兰察布市| 德格县| 台山市| 抚远县| 志丹县| 嘉荫县| 游戏| 龙州县| 华阴市| 台东市| 小金县| 左权县| 禄劝| 昆明市| 汪清县| 华容县| 博乐市| 济源市| 昭觉县| 横山县| 汪清县| 周宁县| 思南县| 绿春县| 怀仁县| 同仁县| 凤翔县| 东方市| 彭山县| 宁武县| 南宫市| 海兴县| 白朗县| 尉氏县| 靖宇县|