欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Shiro:自定義Realm實(shí)現(xiàn)權(quán)限管理方式

 更新時(shí)間:2021年10月25日 10:18:39   作者:小小茶花女  
這篇文章主要介紹了Shiro:自定義Realm實(shí)現(xiàn)權(quán)限管理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Shiro權(quán)限管理

1、權(quán)限管理

權(quán)限管理:不同角色的用戶進(jìn)入到系統(tǒng)能夠完成的操作是不同的,對(duì)不同角色的用戶進(jìn)行的可執(zhí)行操作的管理稱為權(quán)限管理。

2、如何實(shí)現(xiàn)權(quán)限管理

基于主頁(yè)的權(quán)限管理:不同的用戶使用不同的主頁(yè),權(quán)限通過主頁(yè)功能菜單進(jìn)行限制

基于用戶權(quán)限的訪問控制:統(tǒng)權(quán)限表、用戶權(quán)限表、用戶表,比較冗余

基于用戶角色的訪問控制(RBAC):系統(tǒng)權(quán)限表、用戶權(quán)限表、用戶表、角色表、用戶角色表

1、基于JavaSe的Shiro的基本使用

1、導(dǎo)入shiro依賴

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.5.1</version>
</dependency>

但是出現(xiàn)了一點(diǎn)問題:就是引入這個(gè)依賴后pom文件就會(huì)報(bào)錯(cuò),可以在pom文件中加入加入阿里云的代理倉(cāng)庫(kù):

<repositories><!-- 阿里云代碼庫(kù) -->
    <repository>
        <id>maven-ali</id>
        <url>http://maven.aliyun.com/nexus/content/repositories/central</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
            <updatePolicy>always</updatePolicy>
            <checksumPolicy>fail</checksumPolicy>
        </snapshots>
    </repository>
</repositories>

2、創(chuàng)建shiro配置文件:shiro.ini

[users]
zhangsan=123456,seller
lisi=666666,ckmgr
admin=222222,admin
[roles]
admin=*
seller=order-add,order-del,order-list
ckmgr=ck-add,ck-del,ck-list

3、shiro的基本使用

public class TestShiro {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("請(qǐng)輸入用戶名:");
        String username = sc.nextLine();
        System.out.println("請(qǐng)輸入密碼:");
        String password = sc.nextLine();
        //創(chuàng)建安全管理器
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //創(chuàng)建realm
        IniRealm realm = new IniRealm("classpath:shiro.ini");
        //將realm設(shè)置給安全管理器
        securityManager.setRealm(realm);
        //將realm設(shè)置給SecurityUtils工具
        SecurityUtils.setSecurityManager(securityManager);
        //通過SecurityUtils獲取subject對(duì)象
        Subject subject = SecurityUtils.getSubject();
        //認(rèn)證流程
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        System.out.println(subject.isAuthenticated());//false
        //完成認(rèn)證
        subject.login(token);
        System.out.println(subject.isAuthenticated());//true
        //授權(quán)
        //判斷是否有某個(gè)角色
        subject.hasRole("seller");//true
        //判斷是否有某個(gè)權(quán)限
        boolean permitted = subject.isPermitted("oredr-del");
        System.out.println(permitted);//true
    }
}

4、shiro認(rèn)證授權(quán)流程

在這里插入圖片描述

(1) 通過subject.login(token)進(jìn)行登錄,就會(huì)將token包含的用戶信息(賬號(hào)和密碼)傳遞給SecurityManager

(2) SecurityManager會(huì)調(diào)用Authentication進(jìn)行認(rèn)證

(3) Authentication就會(huì)根據(jù)Realm安全信息進(jìn)行認(rèn)證校驗(yàn)

(4) Realm根據(jù)得到的token,調(diào)用doGetAuthenticationInfo()方法進(jìn)行認(rèn)證

(5) 認(rèn)證完成后一層層返回到subject

2、SpringBoot整合shiro

  • 1、導(dǎo)入shiro依賴:
  • 2、配置shiro過濾器:攔截進(jìn)行認(rèn)證和授權(quán)的用戶
  • 3、配置SecurityManager到Spring容器
  • 4、配置Realm(SecurityManager需要Realm)

1. 導(dǎo)入依賴

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.1</version>
</dependency>

2. 配置shiro過濾器

/**
 * Shiro的配置類
 */
@Configuration
public class ShiroConfig {
    //將Realm交給Spring容器創(chuàng)建
    @Bean
    public IniRealm getRealm() {
        IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
        return iniRealm;
    }
    //將DefaultSecurityManager交給Spring容器來創(chuàng)建和管理
    @Bean
    public DefaultSecurityManager getDefaultSecurityManager(IniRealm iniRealm) {
        //SecurityManager要完成認(rèn)證和校驗(yàn)需要Realm
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(iniRealm);
        return securityManager;
    }
    //配置shiro的過濾器
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager securityManager) {
        //過濾器工廠
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
        //過濾器是進(jìn)行權(quán)限校驗(yàn)的核心,進(jìn)行認(rèn)證和授權(quán)需要SecurityManager
        filter.setSecurityManager(securityManager);
        //設(shè)置攔截規(guī)則
        //anon:匿名用戶可以訪問,authc:授權(quán)用戶可以訪問
        Map<String, String> filterMap = new HashMap<>();
        filterMap.put("/","anon");              //項(xiàng)目個(gè)根路徑不攔截
        filterMap.put("/login.html","anon");    //登錄頁(yè)面不攔截
        filterMap.put("/register.html","anon"); //注冊(cè)頁(yè)面不攔截
        filterMap.put("/user/login","anon");    //登錄不攔截
        filterMap.put("/user/regist","anon");   //注冊(cè)不攔截
        filterMap.put("/static/**","anon");     //靜態(tài)頁(yè)面不攔截
        filterMap.put("/**","authc");           //除了上面的請(qǐng)求路徑,其他路徑都要攔截
        filter.setFilterChainDefinitionMap(filterMap);
        //設(shè)置默認(rèn)的登錄頁(yè)面
        filter.setLoginUrl("/login.html");
        //設(shè)置未授權(quán)訪問的頁(yè)面路徑(一個(gè)頁(yè)面如果未授權(quán)讓其跳轉(zhuǎn)到登錄頁(yè)面)
        filter.setUnauthorizedUrl("/login.html");
        return filter;
    }
}

3. 進(jìn)行認(rèn)證測(cè)試

1、UserService:

@Service
public class UserService {
    public void check(String username,String password){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        subject.login(token);
    }
}

2、UserController:

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("/login")
    public String login(String username,String password){
        try {
            userService.check(username,password);
            System.out.println("登錄成功");
            return "index";
        } catch (Exception e) {
            System.out.println("登錄失敗");
            return "login";
        }
    }
}

3、login.html登錄頁(yè)面:

<form action="user/login">
<p>用戶名:<input type="text" name="username"/></p>
<p>密碼:<input type="text" name="password"/></p>
<p><input type="submit" value="登錄"/></p>
</form>

4、shiro.ini配置文件:

[users]
zhangsan=123456

5、認(rèn)證成功:跳到index首頁(yè)

在這里插入圖片描述

6、認(rèn)證失敗,跳到登錄頁(yè)面

3、JdbcRealm實(shí)現(xiàn)權(quán)限管理

在這里插入圖片描述

1. JdbcRealm表結(jié)構(gòu)

這些表名和表結(jié)構(gòu)都是固定的不能更改:

用戶信息表:users

create table users(
    id int primary key auto_increment,
    username varchar(60) not null unique,
    password varchar(20) not null,
    password_salt varchar(20)
)
insert into users(username,password) values("zhangsan","123456");
insert into users(username,password) values("lisi","123456");
insert into users(username,password) values("wangwu","123456");
insert into users(username,password) values("zhaoliu","123456");
insert into users(username,password) values("chenqi","123456");

角色信息表:user_roles

create table user_roles(
    id int primary key auto_increment,
    username varchar(60) not null,
    role_name varchar(100) not null
)
insert into user_roles(username,role_name) values("zhangsan","admin");
insert into user_roles(username,role_name) values("lisi","cmanager"); -- 庫(kù)管人員
insert into user_roles(username,role_name) values("wangwu","xmanager");-- 銷售人員
insert into user_roles(username,role_name) values("zhaoliu","kmanager");-- 客服人員
insert into user_roles(username,role_name) values("chenqi","zmanager"); -- 行政人員

權(quán)限信息表:roles_permissions

create table roles_permissions(
    id int primary key auto_increment,
    role_name varchar(60) not null,
    permission varchar(100) not null
)
-- 管理員具備所有權(quán)限
insert into roles_permissions(role_name,permission) values("admin","*");
-- 庫(kù)管人員
insert into roles_permissions(role_name,permission) values("cmanager","sys:c:save");
insert into roles_permissions(role_name,permission) values("cmanager","sys:c:delete");
insert into roles_permissions(role_name,permission) values("cmanager","sys:c:find");
insert into roles_permissions(role_name,permission) values("cmanager","sys:c:update");
-- 銷售人員
insert into roles_permissions(role_name,permission) values("xmanager","sys:c:save");
insert into roles_permissions(role_name,permission) values("xmanager","sys:x:find");
insert into roles_permissions(role_name,permission) values("xmanager","sys:x:delete");
insert into roles_permissions(role_name,permission) values("xmanager","sys:x:update");
insert into roles_permissions(role_name,permission) values("xmanager","sys:k:save");
insert into roles_permissions(role_name,permission) values("xmanager","sys:k:find");
insert into roles_permissions(role_name,permission) values("xmanager","sys:k:delete");
insert into roles_permissions(role_name,permission) values("xmanager","sys:k:update");
-- 客服人員
insert into roles_permissions(role_name,permission) values("kmanager","sys:k:find");
insert into roles_permissions(role_name,permission) values("kmanager","sys:k:update");
-- 行政人員
insert into roles_permissions(role_name,permission) values("zmanager","sys:k:find");

在這里插入圖片描述

2. 整合JdbcRealm

1、整合Druid和MyBatis:

# 數(shù)據(jù)庫(kù)配置
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/db_shiro1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.druid.username=root
spring.datasource.druid.password=root
# 連接池配置
#連接池建立時(shí)創(chuàng)建的初始化連接數(shù)
spring.datasource.druid.initial-size=5
#連接池中最大的活躍連接數(shù)
spring.datasource.druid.max-active=20
#連接池中最小的活躍連接數(shù)
spring.datasource.druid.min-idle=5
# 配置獲取連接等待超時(shí)的時(shí)間
spring.datasource.druid.max-wait=60000
# mybatis 配置
 mybatis.mapper-locations=classpath:mappers/*Mapper.xml
 mybatis.type-aliases-package=com.hh.beans

2、導(dǎo)入shiro依賴:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.1</version>
</dependency>

3、配置shiro過濾器:只需要將IniRealm 更改為JdbcRealm

@Configuration
public class ShiroConfig {
    @Bean
    public JdbcRealm getJDBCRealm(DataSource dataSource){
        JdbcRealm jdbcRealm = new JdbcRealm();
        //JdbcRealm會(huì)自行從數(shù)據(jù)庫(kù)中查詢用戶和權(quán)限數(shù)據(jù)(前提是數(shù)據(jù)庫(kù)表結(jié)構(gòu)要符合JdbcRealm表結(jié)構(gòu))
        jdbcRealm.setDataSource(dataSource);
        //jdbcRealm默認(rèn)開啟認(rèn)證功能,如果想要開啟授權(quán)功能,需要手動(dòng)開啟
        jdbcRealm.setPermissionsLookupEnabled(true);
        return jdbcRealm;
    }
    //將DefaultSecurityManager交給Spring容器來創(chuàng)建和管理
    @Bean
    public DefaultSecurityManager getDefaultSecurityManager(JdbcRealm jdbcRealm) {
        //SecurityManager要完成認(rèn)證和校驗(yàn)需要Realm
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(jdbcRealm);
        return securityManager;
    }
    //配置shiro的過濾器
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager securityManager) {
        //過濾器工廠
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
        //過濾器是進(jìn)行權(quán)限校驗(yàn)的核心,進(jìn)行認(rèn)證和授權(quán)需要SecurityManager
        filter.setSecurityManager(securityManager);
        //設(shè)置攔截規(guī)則
        //anon:匿名用戶可以訪問,authc:授權(quán)用戶可以訪問
        Map<String, String> filterMap = new HashMap<>();
        filterMap.put("/", "anon");              //項(xiàng)目個(gè)根路徑不攔截
        filterMap.put("/login.html", "anon");    //登錄頁(yè)面不攔截
        filterMap.put("/register.html", "anon"); //注冊(cè)頁(yè)面不攔截
        filterMap.put("/user/login", "anon");    //登錄不攔截
        filterMap.put("/user/regist", "anon");   //注冊(cè)不攔截
        filterMap.put("/static/**", "anon");     //靜態(tài)頁(yè)面不攔截
        filterMap.put("/**", "authc");           //除了上面的請(qǐng)求路徑,其他路徑都要攔截
        filter.setFilterChainDefinitionMap(filterMap);
        //設(shè)置默認(rèn)的登錄頁(yè)面
        filter.setLoginUrl("/login.html");
        //設(shè)置未授權(quán)訪問的頁(yè)面路徑(一個(gè)頁(yè)面如果未授權(quán)讓其跳轉(zhuǎn)到登錄頁(yè)面)
        filter.setUnauthorizedUrl("/login.html");
        return filter;
    }
}

4、進(jìn)行認(rèn)證測(cè)試:和上面測(cè)試方法相同

由于只要我們按照規(guī)定寫了數(shù)據(jù)庫(kù)表結(jié)構(gòu),那么既可以直接使用數(shù)據(jù)庫(kù)中的信息

在這里插入圖片描述

4、實(shí)現(xiàn)前端的權(quán)限菜單展示

1. 在Thymeleaf中使用標(biāo)簽

1、在pom.xml文件中導(dǎo)入thymeleaf模版對(duì)shiro標(biāo)簽支持的依賴

<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>

2、在ShiroConfig中配置Shiro的方言:

@Bean
public ShiroDialect getShiroDialect(){
    return new ShiroDialect();
}

3、Thymeleaf模版中引入shiro的命名空間:

<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
...
</html>

2. 常用標(biāo)簽

2.1 guest

判斷用戶是否是游客身份,如果是游客身份則顯示此標(biāo)簽內(nèi)容

<shiro:guest>
歡迎游客,<a href="login.html" rel="external nofollow"  rel="external nofollow" >請(qǐng)登錄</a>
</shiro:guest>

2.2 user

判斷用戶是否是認(rèn)證身份,如果是認(rèn)證身份則顯示此標(biāo)簽內(nèi)容

<shiro:user>
已登錄用戶
</shiro:user>

在這里插入圖片描述

2.3 principal

獲取當(dāng)前登錄用戶名

<shiro:user>
已登錄用戶<shiro:principal/>歡迎您!
</shiro:user>

在這里插入圖片描述

2.4 hasRole

當(dāng)期那登錄用戶的角色

<shiro:user>
當(dāng)前用戶<shiro:principal/>歡迎您!
當(dāng)前用戶為<shiro:hasRole name="admin">超級(jí)管理員</shiro:hasRole>
<shiro:hasRole name="cmanager">倉(cāng)管人員</shiro:hasRole>
<shiro:hasRole name="xmanager">銷售人員</shiro:hasRole>
<shiro:hasRole name="kmanager">客服人員</shiro:hasRole>
<shiro:hasRole name="zmanager">行政人員</shiro:hasRole>
</shiro:user>

登錄用戶為zhangsan:

在這里插入圖片描述

登錄用戶為lisi:

在這里插入圖片描述

2.5 hasPermission

當(dāng)前登錄用戶具有的權(quán)限

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<shiro:guest>
歡迎游客,<a href="login.html" rel="external nofollow"  rel="external nofollow" >請(qǐng)登錄</a>
</shiro:guest>
<shiro:user>
當(dāng)前用戶<shiro:principal/>歡迎您!
當(dāng)前用戶為<shiro:hasRole name="admin">超級(jí)管理員</shiro:hasRole>
<shiro:hasRole name="cmanager">倉(cāng)管人員</shiro:hasRole>
<shiro:hasRole name="xmanager">銷售人員</shiro:hasRole>
<shiro:hasRole name="kmanager">客服人員</shiro:hasRole>
<shiro:hasRole name="zmanager">行政人員</shiro:hasRole>
</shiro:user>
倉(cāng)庫(kù)管理:
<ul>
<shiro:hasPermission name="sys:c:save"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >入庫(kù)</a> </li></shiro:hasPermission>
<shiro:hasPermission name="sys:c:delete"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >出庫(kù)</a> </li></shiro:hasPermission>
<shiro:hasPermission name="sys:c:update"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >修改</a> </li></shiro:hasPermission>
<shiro:hasPermission name="sys:c:find"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >查詢</a> </li></shiro:hasPermission>
</ul>
訂單管理:
<ul>
<shiro:hasPermission name="sys:x:save"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >添加訂單</a> </li></shiro:hasPermission>
<shiro:hasPermission name="sys:x:delete"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >刪除訂單</a> </li></shiro:hasPermission>
<shiro:hasPermission name="sys:x:update"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >修改訂單</a> </li></shiro:hasPermission>
<shiro:hasPermission name="sys:x:find"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >查詢訂單</a> </li></shiro:hasPermission>
</ul>
客戶管理:
<ul>
<shiro:hasPermission name="sys:k:save"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >添加客戶</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:k:delete"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >刪除客戶</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:k:update"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >修改客戶</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:k:find"><li><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >查詢客戶</a></li></shiro:hasPermission>
</ul>
</body>
</html>

登錄用戶為:lisi

在這里插入圖片描述

登錄用戶為zhangsan:

在這里插入圖片描述

3. 認(rèn)證流程回顧

在這里插入圖片描述

5、自定義Realm實(shí)現(xiàn)權(quán)限管理

1. 表結(jié)構(gòu)的設(shè)計(jì)

1.1 用戶表:tb_users

create table tb_users(
    user_id int primary key auto_increment,
    username varchar(60) not null unique,
    password varchar(20) not null,
    password_salt varchar(60)
);
insert into tb_users(username,password) values("zhangsan","123456");
insert into tb_users(username,password) values("lisi","123456");
insert into tb_users(username,password) values("wangwu","123456");
insert into tb_users(username,password) values("zhaoliu","123456");
insert into tb_users(username,password) values("chenqi","123456");

1.2 角色表:tb_roles

create table tb_roles(
    role_id int primary key auto_increment,
    role_name varchar(100) not null
);
insert into tb_roles(role_name) values("admin");
insert into tb_roles(role_name) values("cmanager");
insert into tb_roles(role_name) values("xmanager");
insert into tb_roles(role_name) values("kmanager");
insert into tb_roles(role_name) values("zmanager");

1.3 權(quán)限表:tb_permissions

create table tb_permissions(
    permission_id int primary key auto_increment,
    permission_code varchar(20) not null,
    permission_name varchar(60) 
);
insert into tb_permissions(permission_code,permission_name) values("sys:c:save","入庫(kù)");
insert into tb_permissions(permission_code,permission_name) values("sys:c:delete","出庫(kù)");
insert into tb_permissions(permission_code,permission_name) values("sys:c:update","修改");
insert into tb_permissions(permission_code,permission_name) values("sys:c:find","查詢");
insert into tb_permissions(permission_code,permission_name) values("sys:x:save","新增訂單");
insert into tb_permissions(permission_code,permission_name) values("sys:x:delete","刪除訂單");
insert into tb_permissions(permission_code,permission_name) values("sys:x:update","修改訂單");
insert into tb_permissions(permission_code,permission_name) values("sys:x:find","查詢訂單");
insert into tb_permissions(permission_code,permission_name) values("sys:k:save","新增客戶");
insert into tb_permissions(permission_code,permission_name) values("sys:k:delete","刪除客戶");
insert into tb_permissions(permission_code,permission_name) values("sys:k:update","修改客戶");
insert into tb_permissions(permission_code,permission_name) values("sys:k:find","查詢客戶");

1.4 用戶角色表:tb_urs

create table tb_urs(
    uid int not null,
    rid int not null
    -- primary key(uid,rid),
    -- constraint FK_user foreign key(uid) references tb_users(user_id),
    -- constraint FK_role foreign key(rid) references tb_rolls(roll_id)
);
-- zhangsan具有所有角色,代表具有所有權(quán)限,不用給他分配權(quán)限
insert into tb_urs(uid,rid) values(1,1);-- zhangsan用戶具有admin角色
insert into tb_urs(uid,rid) values(1,2);-- zhangsan用戶具有cmanager角色
insert into tb_urs(uid,rid) values(1,3);-- zhangsan用戶具有xmanager角色
insert into tb_urs(uid,rid) values(1,4);-- zhangsan用戶具有kmanagerr角色
insert into tb_urs(uid,rid) values(1,5);-- zhangsan用戶具有zmanager角色
insert into tb_urs(uid,rid) values(2,2);-- lisi用戶具有cmanager角色
insert into tb_urs(uid,rid) values(3,3);-- wangwu用戶具有xmanager角色
insert into tb_urs(uid,rid) values(4,4);-- zhaoliu用戶具有kmanager角色
insert into tb_urs(uid,rid) values(5,5);-- chenqi用戶具有zmanager角色

1.5 角色權(quán)限表:tb_rps

create table tb_rps(
	rid int not null,
    pid int not null
);
-- 給角色2(倉(cāng)管)分配權(quán)限
insert into tb_rps(rid,pid) values(2,1);
insert into tb_rps(rid,pid) values(2,2);
insert into tb_rps(rid,pid) values(2,3);
insert into tb_rps(rid,pid) values(2,4);
-- 給角色3(銷售)分配權(quán)限
insert into tb_rps(rid,pid) values(3,3);
insert into tb_rps(rid,pid) values(3,5);
insert into tb_rps(rid,pid) values(3,6);
insert into tb_rps(rid,pid) values(3,7);
insert into tb_rps(rid,pid) values(3,8);
insert into tb_rps(rid,pid) values(3,9);
insert into tb_rps(rid,pid) values(3,10);
insert into tb_rps(rid,pid) values(3,11);
insert into tb_rps(rid,pid) values(3,12);
-- 給角色4(客服)分配權(quán)限
insert into tb_rps(rid,pid) values(4,11);
insert into tb_rps(rid,pid) values(4,12);
-- 給角色5(行政)分配權(quán)限
insert into tb_rps(rid,pid) values(5,4);
insert into tb_rps(rid,pid) values(5,8);
insert into tb_rps(rid,pid) values(5,12);

2. Dao層實(shí)現(xiàn)

在這里插入圖片描述

shiro 進(jìn)行認(rèn)證需要用戶信息:

  • 根據(jù)用戶名查詢用戶信息

shiro進(jìn)行權(quán)限管理需要當(dāng)前用戶的角色和權(quán)限:

  • 根據(jù)用戶名查詢當(dāng)前用戶的角色列表
  • 根據(jù)用戶名查詢當(dāng)前用戶的權(quán)限列表

2.1 根據(jù)用戶名查詢用戶信息

實(shí)體類User

@Data
public class User {
    private String userId;
    private String userName;
    private String userPwd;
    private String pwdSalt;
}

dao接口

@Mapper
public interface UserDao {
    //根據(jù)用戶名查詢用戶信息
    public User queryUserByUsername(String username) throws Exception;
}

映射配置

<?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.hh.dao.UserDao">
    <resultMap id="userMap" type="User">
        <id column="user_id" property="userId"></id>
        <result column="username" property="userName"/>
        <result column="password" property="userPwd"/>
        <result column="password_salt" property="pwdSalt"/>
    </resultMap>
    <select id="queryUserByUsername" resultMap="userMap">
        select * from tb_users
        where username=#{username}
    </select>
</mapper>

2.2 根據(jù)用戶名查詢角色信息

dao接口

@Mapper
public interface RoleDao {
    public Set<String> queryRoleNamesByUsername(String username) throws Exception;
}

映射配置

<?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.hh.dao.RoleDao">
    <select id="queryRoleNamesByUsername" resultSets="java.util.Set" resultType="string">
        select 
            role_name
        from 
            tb_users  
        join 
            tb_urs
        on 
            tb_users.user_id = tb_urs.uid
        join 
            tb_roles
        on 
            tb_urs.rid = tb_roles.role_id
        where 
            tb_users.username=#{username}
    </select>
</mapper>

2.3 根據(jù)用戶名查詢權(quán)限列表

dao接口

public interface PermissionDAO {
    public Set<String> queryPermissionsByUsername(String  username) throws Exception;
}

映射配置

<?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.hh.dao.PermissionDao">
    <select id="queryPermissionsByUsername" resultSets="java.util.Set" resultType="string">
        select 
            tb_permissions.permission_code 
        from 
            tb_users
        join 
            tb_urs 
        on 
            tb_users.user_id=tb_urs.uid
        join 
            tb_roles 
        on 
            tb_urs.rid=tb_roles.role_id
        join 
            tb_rps 
        on 
            tb_roles.role_id=tb_rps.rid
        join 
            tb_permissions 
        on 
            tb_rps.pid=tb_permissions.permission_id
        where 
            tb_users.username=#{username}
    </select>
</mapper>

3. 整合Shiro

3.1 導(dǎo)入依賴

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.1</version>
</dependency>
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>

3.2 配置Shiro過濾器

@Configuration
public class ShiroConfig {
    //1、配置Shiro的方言支持
    //2、配置Realm
    //3、配置SecurityManager
    //4、配置過濾器
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
    //自定義Realm,Realm相當(dāng)于數(shù)據(jù)源,從數(shù)據(jù)庫(kù)中查詢出認(rèn)證信息和授權(quán)信息
    @Bean
    public MyRealm getRealm(){
        MyRealm myRealm = new MyRealm();
        return myRealm;
    }
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(MyRealm myRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm);
        return securityManager;
    }
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
        //過濾器就是shiro就行權(quán)限校驗(yàn)的核心,進(jìn)行認(rèn)證和授權(quán)是需要SecurityManager的
        filter.setSecurityManager(securityManager);
        Map<String,String> filterMap = new HashMap<>();
        filterMap.put("/","anon");
        filterMap.put("/index.html","anon");
        filterMap.put("/login.html","anon");
        filterMap.put("/regist.html","anon");
        filterMap.put("/user/login","anon");
        filterMap.put("/user/regist","anon");
        filterMap.put("/layui/**","anon");
        filterMap.put("/**","authc");
        filter.setFilterChainDefinitionMap(filterMap);
        filter.setLoginUrl("/login.html");
        //設(shè)置未授權(quán)訪問的頁(yè)面路徑()
        filter.setUnauthorizedUrl("/login.html");
        return filter;
    }
}

3.3 自定義Realm

/**
 * 自定義Realm的規(guī)范:
 * 1、創(chuàng)建一個(gè)類實(shí)現(xiàn)AuthorizingRealm,重寫里面的兩個(gè)方法
 * 2、重寫getName()方法,返回當(dāng)前Realm的自定義名稱
 */
public class MyRealm extends AuthorizingRealm {
    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private PermissionDao permissionDao;
    public String getName(){
        return "myRealm";
    }
    /**
     * 獲取認(rèn)證信息:將用戶密碼查詢出來交給shiro
     * @param authenticationToken token就是傳遞的 subject.login(token)
     */
    @SneakyThrows
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //從token中獲取用戶名
        String username = token.getUsername();
        //根據(jù)用戶名到數(shù)據(jù)庫(kù)中查詢用戶信息
        User user = userDao.queryUserByUsername(username);
        if(user==null){
            return null;
        }
        //將查詢出來的密碼封裝成安全信息給shiro
        AuthenticationInfo info = new SimpleAuthenticationInfo(
                username,//當(dāng)前用戶的用戶名
                user.getUserPwd(),//從數(shù)據(jù)庫(kù)中查詢出來的安全數(shù)據(jù)
                getName()
                );
        return info;
    }
    /**
     * 獲取授權(quán)信息:將當(dāng)前用戶的角色和權(quán)限查詢出交給shiro
     * @param principalCollection
     */
    @SneakyThrows
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //獲取用戶的用戶名
        String username = (String)principalCollection.iterator().next();
        //根據(jù)用戶名查詢用戶的角色列表
        Set<String> roleNames = roleDao.queryRoleNamesByUsername(username);
        //根據(jù)用戶名查詢用戶的權(quán)限列表
        Set<String> ps = permissionDao.queryPermissionsByUsername(username);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roleNames);
        info.setStringPermissions(ps);
        return info;
    }
}

測(cè)試結(jié)果:

在這里插入圖片描述 

在這里插入圖片描述

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java數(shù)組的基本操作方法整理

    Java數(shù)組的基本操作方法整理

    這篇文章主要給大家介紹了關(guān)于Java中數(shù)組的定義和使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • Map集合中獲取key-value值的實(shí)現(xiàn)方法

    Map集合中獲取key-value值的實(shí)現(xiàn)方法

    這篇文章主要介紹了Map集合中獲取key-value值的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java多態(tài)的全面系統(tǒng)解析

    Java多態(tài)的全面系統(tǒng)解析

    多態(tài)就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量到底會(huì)指向哪個(gè)類的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定
    2022-03-03
  • Mybatis實(shí)戰(zhàn)之TypeHandler高級(jí)進(jìn)階

    Mybatis實(shí)戰(zhàn)之TypeHandler高級(jí)進(jìn)階

    本文主要介紹了自定義的枚舉TypeHandler的相關(guān)知識(shí),具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • Java的ConcurrentHashMap中不能存儲(chǔ)null的原因解析

    Java的ConcurrentHashMap中不能存儲(chǔ)null的原因解析

    眾所周知,在Java中Map可以存儲(chǔ)null,而ConcurrentHashMap不能存儲(chǔ)null值,那么為什么呢?今天通過源碼分析給大家詳細(xì)解讀,感興趣的朋友一起看看吧
    2022-07-07
  • spring中實(shí)現(xiàn)容器加載完成后再執(zhí)行自己的方法

    spring中實(shí)現(xiàn)容器加載完成后再執(zhí)行自己的方法

    這篇文章主要介紹了spring中實(shí)現(xiàn)容器加載完成后再執(zhí)行自己的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • SpringBoot中的Aop用法示例詳解

    SpringBoot中的Aop用法示例詳解

    這篇文章主要介紹了SpringBoot中的Aop用法,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • maven的安裝配置以及在IDEA中的配置圖文教程

    maven的安裝配置以及在IDEA中的配置圖文教程

    下面小編就為大家分享一篇maven的安裝配置以及在IDEA中的配置圖文教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • mybatis-plus實(shí)現(xiàn)自定義SQL、多表查詢與多表分頁(yè)查詢語句實(shí)例

    mybatis-plus實(shí)現(xiàn)自定義SQL、多表查詢與多表分頁(yè)查詢語句實(shí)例

    mybatisplus是個(gè)很好用的插件,相信小伙伴們都知道,下面這篇文章主要給大家介紹了關(guān)于mybatis-plus實(shí)現(xiàn)自定義SQL、多表查詢與多表分頁(yè)查詢語句的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • Java如何基于反射機(jī)制獲取不同的類

    Java如何基于反射機(jī)制獲取不同的類

    這篇文章主要介紹了Java如何基于反射機(jī)制獲取不同的類,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08

最新評(píng)論