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

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

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

Spring Security簡介

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

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

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

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

-- 創(chuàng)建用戶表
CREATE TABLE `user` (
  -- 主鍵id,自增
  `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '用戶id',
  -- 用戶名字段
  `username` VARCHAR(32) DEFAULT NULL COMMENT '用戶名',
  -- 密碼字段(建議存儲加密后的密碼)
  `password` VARCHAR(255) DEFAULT NULL COMMENT '密碼',
  -- 賬戶啟用狀態(tài):1=啟用,0=禁用
  `enabled` TINYINT(1) DEFAULT NULL COMMENT '是否可用',
  -- 賬戶未過期標志:1=未過期,0=已過期
  `accountNonExpired` TINYINT(1) DEFAULT NULL COMMENT '賬戶過期',
  -- 賬戶未鎖定標志:1=未鎖定,0=已鎖定  
  `accountNonLocked` TINYINT(1) DEFAULT NULL COMMENT '賬戶鎖定',
  -- 憑證未過期標志:1=未過期,0=已過期
  `credentialsNonExpired` TINYINT(1) DEFAULT NULL COMMENT '憑證過期',
  -- 設置主鍵
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 創(chuàng)建角色表(使用roles避免與MySQL關鍵字沖突)
CREATE TABLE `roles` (
  -- 主鍵id,自增
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  -- 角色英文名,如ROLE_ADMIN
  `name` VARCHAR(32) DEFAULT NULL,
  -- 角色中文名,如管理員
  `name_zh` VARCHAR(32) DEFAULT NULL,
  -- 設置主鍵
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 創(chuàng)建用戶角色關聯(lián)表(多對多關系)
CREATE TABLE `user_role` (
  -- 主鍵id,自增
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  -- 用戶id,關聯(lián)user表
  `uid` INT(11) DEFAULT NULL,
  -- 角色id,關聯(lián)roles表
  `rid` INT(11) DEFAULT NULL,
  -- 設置主鍵
  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個測試用戶
INSERT INTO `user` (
    `username`, 
    `password`, 
    `enabled`, 
    `accountNonExpired`, 
    `accountNonLocked`, 
    `credentialsNonExpired`
) VALUES 
-- 管理員用戶:全部狀態(tài)正常
('admin', 'admin123', 1, 1, 1, 1),
-- 普通用戶:正??捎?
('zhangsan', '123456', 1, 1, 1, 1),
-- 被禁用的用戶:用于測試禁用功能
('lisi', '123456', 0, 1, 1, 1);
-- ==================== 第二步:插入角色數(shù)據(jù) ====================
-- 插入幾個常用角色
INSERT INTO `roles` (`name`, `name_zh`) VALUES 
('ROLE_ADMIN', '管理員'),
('ROLE_USER', '普通用戶'),
('ROLE_GUEST', '訪客');
-- ==================== 第三步:插入用戶角色關聯(lián) ====================
-- 給用戶分配角色
INSERT INTO `user_role` (`uid`, `rid`) VALUES 
-- admin用戶:同時擁有管理員和普通用戶角色
(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

四、編寫實體類、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是因為SpringSecurity低層只認這個,相當于不良人只認大帥不認令牌*/
    private Integer id; // 用戶id
    private String username;    // 用戶名
    private String password;    // 密碼
    private boolean enabled;    // 是否可用
    private boolean accountNonExpired;  // 賬戶過期
    private boolean accountNonLocked;   // 賬戶鎖定
    private boolean credentialsNonExpired;  // 憑證過期
    private List<Roles> roles = new ArrayList<>();   // 用戶角色信息
    // 返回權限信息
    @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自動生成構造函數(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("用戶不存在");
        }
        //這里因為沒有配置密碼格式,后臺數(shù)據(jù)庫如果是明文的話,就需要用這個暫時“過渡”一下
        user.setPassword("{noop}" + user.getPassword());
        List<Roles> roles = rolesMapper.queryRolesByName(user.getId());
        user.setRoles(roles);
        return user;
    }
}

六、測試運行

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

相關文章

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

    一文詳解jvm中的引用類型

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

    已有的springcloud+mybatis項目升級為mybatis-plus的方法

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

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

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

    Java使用POI-TL實現(xiàn)生成有個性的簡歷

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

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

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

    IDEA 集成log4j將SQL語句打印在控制臺上的實現(xiàn)操作

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

    Mybatis 的 Interceptor(攔截器) 與 JSqlparser&

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

    Dubbo無法訪問遠程Zookeeper已注冊服務的問題解決方案

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

    Spring組件實例化擴展點之InstantiationAwareBeanPostProcessor使用場景解析

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

    在idea中全局引入并運行ElementUI方式

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

最新評論

原阳县| 丹凤县| 横峰县| 临夏市| 瓮安县| 云南省| 南和县| 拉孜县| 油尖旺区| 遂溪县| 云浮市| 右玉县| 寿光市| 宝兴县| 天全县| 瑞丽市| 哈尔滨市| 洛隆县| 平凉市| 泸水县| 六盘水市| 仁布县| 桂林市| 封丘县| 大冶市| 兴文县| 陕西省| 北碚区| 古浪县| 乐业县| 灵宝市| 扎兰屯市| 朔州市| 日喀则市| 永兴县| 丰台区| 视频| 沧州市| 景宁| 福泉市| 孙吴县|