一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Shiro:自定義Realm實現權限管理方式

Shiro:自定義Realm實現權限管理方式

2022-02-27 15:23小小茶花女 Java教程

這篇文章主要介紹了Shiro:自定義Realm實現權限管理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Shiro權限管理

1、權限管理

權限管理:不同角色的用戶進入到系統能夠完成的操作是不同的,對不同角色的用戶進行的可執行操作的管理稱為權限管理。

2、如何實現權限管理

基于主頁的權限管理:不同的用戶使用不同的主頁,權限通過主頁功能菜單進行限制

基于用戶權限的訪問控制:統權限表、用戶權限表、用戶表,比較冗余

基于用戶角色的訪問控制(RBAC):系統權限表、用戶權限表、用戶表、角色表、用戶角色表

 

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

1、導入shiro依賴

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

但是出現了一點問題:就是引入這個依賴后pom文件就會報錯,可以在pom文件中加入加入阿里云的代理倉庫:

<repositories><!-- 阿里云代碼庫 -->
  <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、創建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("請輸入用戶名:");
      String username = sc.nextLine();
      System.out.println("請輸入密碼:");
      String password = sc.nextLine();
      //創建安全管理器
      DefaultSecurityManager securityManager = new DefaultSecurityManager();
      //創建realm
      IniRealm realm = new IniRealm("classpath:shiro.ini");
      //將realm設置給安全管理器
      securityManager.setRealm(realm);
      //將realm設置給SecurityUtils工具
      SecurityUtils.setSecurityManager(securityManager);
      //通過SecurityUtils獲取subject對象
      Subject subject = SecurityUtils.getSubject();
      //認證流程
      UsernamePasswordToken token = new UsernamePasswordToken(username, password);
      System.out.println(subject.isAuthenticated());//false
      //完成認證
      subject.login(token);
      System.out.println(subject.isAuthenticated());//true
      //授權
      //判斷是否有某個角色
      subject.hasRole("seller");//true
      //判斷是否有某個權限
      boolean permitted = subject.isPermitted("oredr-del");
      System.out.println(permitted);//true
  }
}

4、shiro認證授權流程

Shiro:自定義Realm實現權限管理方式

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

(2) SecurityManager會調用Authentication進行認證

(3) Authentication就會根據Realm安全信息進行認證校驗

(4) Realm根據得到的token,調用doGetAuthenticationInfo()方法進行認證

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

 

2、SpringBoot整合shiro

  • 1、導入shiro依賴:
  • 2、配置shiro過濾器:攔截進行認證和授權的用戶
  • 3、配置SecurityManager到Spring容器
  • 4、配置Realm(SecurityManager需要Realm)

1. 導入依賴

<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容器創建
  @Bean
  public IniRealm getRealm() {
      IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
      return iniRealm;
  }
  //將DefaultSecurityManager交給Spring容器來創建和管理
  @Bean
  public DefaultSecurityManager getDefaultSecurityManager(IniRealm iniRealm) {
      //SecurityManager要完成認證和校驗需要Realm
      DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
      securityManager.setRealm(iniRealm);
      return securityManager;
  }
  //配置shiro的過濾器
  @Bean
  public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager securityManager) {
      //過濾器工廠
      ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
      //過濾器是進行權限校驗的核心,進行認證和授權需要SecurityManager
      filter.setSecurityManager(securityManager);
      //設置攔截規則
      //anon:匿名用戶可以訪問,authc:授權用戶可以訪問
      Map<String, String> filterMap = new HashMap<>();
      filterMap.put("/","anon");              //項目個根路徑不攔截
      filterMap.put("/login.html","anon");    //登錄頁面不攔截
      filterMap.put("/register.html","anon"); //注冊頁面不攔截
      filterMap.put("/user/login","anon");    //登錄不攔截
      filterMap.put("/user/regist","anon");   //注冊不攔截
      filterMap.put("/static/**","anon");     //靜態頁面不攔截
      filterMap.put("/**","authc");           //除了上面的請求路徑,其他路徑都要攔截
      filter.setFilterChainDefinitionMap(filterMap);
      //設置默認的登錄頁面
      filter.setLoginUrl("/login.html");
      //設置未授權訪問的頁面路徑(一個頁面如果未授權讓其跳轉到登錄頁面)
      filter.setUnauthorizedUrl("/login.html");
      return filter;
  }
}

3. 進行認證測試

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登錄頁面:

<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、認證成功:跳到index首頁

Shiro:自定義Realm實現權限管理方式

6、認證失敗,跳到登錄頁面

 

3、JdbcRealm實現權限管理

Shiro:自定義Realm實現權限管理方式

1. JdbcRealm表結構

這些表名和表結構都是固定的不能更改:

用戶信息表: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"); -- 庫管人員
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"); -- 行政人員

權限信息表:roles_permissions

create table roles_permissions(
  id int primary key auto_increment,
  role_name varchar(60) not null,
  permission varchar(100) not null
)
-- 管理員具備所有權限
insert into roles_permissions(role_name,permission) values("admin","*");
-- 庫管人員
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");

Shiro:自定義Realm實現權限管理方式

2. 整合JdbcRealm

1、整合Druid和MyBatis:

# 數據庫配置
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
# 連接池配置
#連接池建立時創建的初始化連接數
spring.datasource.druid.initial-size=5
#連接池中最大的活躍連接數
spring.datasource.druid.max-active=20
#連接池中最小的活躍連接數
spring.datasource.druid.min-idle=5
# 配置獲取連接等待超時的時間
spring.datasource.druid.max-wait=60000
# mybatis 配置
mybatis.mapper-locations=classpath:mappers/*Mapper.xml
mybatis.type-aliases-package=com.hh.beans

2、導入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會自行從數據庫中查詢用戶和權限數據(前提是數據庫表結構要符合JdbcRealm表結構)
      jdbcRealm.setDataSource(dataSource);
      //jdbcRealm默認開啟認證功能,如果想要開啟授權功能,需要手動開啟
      jdbcRealm.setPermissionsLookupEnabled(true);
      return jdbcRealm;
  }
  //將DefaultSecurityManager交給Spring容器來創建和管理
  @Bean
  public DefaultSecurityManager getDefaultSecurityManager(JdbcRealm jdbcRealm) {
      //SecurityManager要完成認證和校驗需要Realm
      DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
      securityManager.setRealm(jdbcRealm);
      return securityManager;
  }
  //配置shiro的過濾器
  @Bean
  public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager securityManager) {
      //過濾器工廠
      ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
      //過濾器是進行權限校驗的核心,進行認證和授權需要SecurityManager
      filter.setSecurityManager(securityManager);
      //設置攔截規則
      //anon:匿名用戶可以訪問,authc:授權用戶可以訪問
      Map<String, String> filterMap = new HashMap<>();
      filterMap.put("/", "anon");              //項目個根路徑不攔截
      filterMap.put("/login.html", "anon");    //登錄頁面不攔截
      filterMap.put("/register.html", "anon"); //注冊頁面不攔截
      filterMap.put("/user/login", "anon");    //登錄不攔截
      filterMap.put("/user/regist", "anon");   //注冊不攔截
      filterMap.put("/static/**", "anon");     //靜態頁面不攔截
      filterMap.put("/**", "authc");           //除了上面的請求路徑,其他路徑都要攔截
      filter.setFilterChainDefinitionMap(filterMap);
      //設置默認的登錄頁面
      filter.setLoginUrl("/login.html");
      //設置未授權訪問的頁面路徑(一個頁面如果未授權讓其跳轉到登錄頁面)
      filter.setUnauthorizedUrl("/login.html");
      return filter;
  }
}

4、進行認證測試:和上面測試方法相同

由于只要我們按照規定寫了數據庫表結構,那么既可以直接使用數據庫中的信息

Shiro:自定義Realm實現權限管理方式

 

4、實現前端的權限菜單展示

1. 在Thymeleaf中使用標簽

1、在pom.xml文件中導入thymeleaf模版對shiro標簽支持的依賴

<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. 常用標簽

2.1 guest

判斷用戶是否是游客身份,如果是游客身份則顯示此標簽內容

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

2.2 user

判斷用戶是否是認證身份,如果是認證身份則顯示此標簽內容

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

Shiro:自定義Realm實現權限管理方式

2.3 principal

獲取當前登錄用戶名

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

Shiro:自定義Realm實現權限管理方式

2.4 hasRole

當期那登錄用戶的角色

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

登錄用戶為zhangsan:

Shiro:自定義Realm實現權限管理方式

登錄用戶為lisi:

Shiro:自定義Realm實現權限管理方式

2.5 hasPermission

當前登錄用戶具有的權限

<!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" >請登錄</a>
</shiro:guest>
<shiro:user>
當前用戶<shiro:principal/>歡迎您!
當前用戶為<shiro:hasRole name="admin">超級管理員</shiro:hasRole>
<shiro:hasRole name="cmanager">倉管人員</shiro:hasRole>
<shiro:hasRole name="xmanager">銷售人員</shiro:hasRole>
<shiro:hasRole name="kmanager">客服人員</shiro:hasRole>
<shiro:hasRole name="zmanager">行政人員</shiro:hasRole>
</shiro:user>
倉庫管理:
<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" >入庫</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" >出庫</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

Shiro:自定義Realm實現權限管理方式

登錄用戶為zhangsan:

Shiro:自定義Realm實現權限管理方式

3. 認證流程回顧

Shiro:自定義Realm實現權限管理方式

 

5、自定義Realm實現權限管理

1. 表結構的設計

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 權限表: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","入庫");
insert into tb_permissions(permission_code,permission_name) values("sys:c:delete","出庫");
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具有所有角色,代表具有所有權限,不用給他分配權限
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 角色權限表:tb_rps

create table tb_rps(
	rid int not null,
  pid int not null
);
-- 給角色2(倉管)分配權限
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(銷售)分配權限
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(客服)分配權限
insert into tb_rps(rid,pid) values(4,11);
insert into tb_rps(rid,pid) values(4,12);
-- 給角色5(行政)分配權限
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層實現

Shiro:自定義Realm實現權限管理方式

shiro 進行認證需要用戶信息:

  • 根據用戶名查詢用戶信息

shiro進行權限管理需要當前用戶的角色和權限:

  • 根據用戶名查詢當前用戶的角色列表
  • 根據用戶名查詢當前用戶的權限列表

2.1 根據用戶名查詢用戶信息

實體類User

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

dao接口

@Mapper
public interface UserDao {
  //根據用戶名查詢用戶信息
  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 根據用戶名查詢角色信息

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 根據用戶名查詢權限列表

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 導入依賴

<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相當于數據源,從數據庫中查詢出認證信息和授權信息
  @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就行權限校驗的核心,進行認證和授權是需要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");
      //設置未授權訪問的頁面路徑()
      filter.setUnauthorizedUrl("/login.html");
      return filter;
  }
}

3.3 自定義Realm

/**
* 自定義Realm的規范:
* 1、創建一個類實現AuthorizingRealm,重寫里面的兩個方法
* 2、重寫getName()方法,返回當前Realm的自定義名稱
*/
public class MyRealm extends AuthorizingRealm {
  @Autowired
  private UserDao userDao;
  @Autowired
  private RoleDao roleDao;
  @Autowired
  private PermissionDao permissionDao;
  public String getName(){
      return "myRealm";
  }
  /**
   * 獲取認證信息:將用戶密碼查詢出來交給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();
      //根據用戶名到數據庫中查詢用戶信息
      User user = userDao.queryUserByUsername(username);
      if(user==null){
          return null;
      }
      //將查詢出來的密碼封裝成安全信息給shiro
      AuthenticationInfo info = new SimpleAuthenticationInfo(
              username,//當前用戶的用戶名
              user.getUserPwd(),//從數據庫中查詢出來的安全數據
              getName()
              );
      return info;
  }
  /**
   * 獲取授權信息:將當前用戶的角色和權限查詢出交給shiro
   * @param principalCollection
   */
  @SneakyThrows
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
      //獲取用戶的用戶名
      String username = (String)principalCollection.iterator().next();
      //根據用戶名查詢用戶的角色列表
      Set<String> roleNames = roleDao.queryRoleNamesByUsername(username);
      //根據用戶名查詢用戶的權限列表
      Set<String> ps = permissionDao.queryPermissionsByUsername(username);
      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      info.setRoles(roleNames);
      info.setStringPermissions(ps);
      return info;
  }
}

測試結果:

Shiro:自定義Realm實現權限管理方式

Shiro:自定義Realm實現權限管理方式

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://hengheng.blog.csdn.net/article/details/106980159

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩影院在线观看 | 逼逼爱 | 亚洲成av人片天堂网 | 亚洲天堂成人在线观看 | 2020国产精品永久在线观看 | 黄漫在线播放 | 三级黄色片在线免费观看 | 亚洲一区二区三区福利在线 | 调教校花浣肠开菊 | 欧美日韩一区二区综合 | 亚州性夜夜射在线观看 | 果冻传媒在线播放1 | 性姿势女人嗷嗷叫图片 | 视频一区在线观看 | 甜蜜调教| 久久99re热在线播放7 | 日韩亚洲欧美综合一区二区三区 | 青柠影院在线观看免费完整版1 | kayden·kross hd在线| 亚洲欧美国产精品完整版 | 草莓绿巨人香蕉茄子芭乐 | 亚洲国产美女精品久久久久 | 午夜精品久久久 | 欧美1级| 精品蜜臀AV在线天堂 | 九九精品视频在线观看 | 国产精品成人亚洲 | 日本肉体xxxx69xxxx| 91尤物在线播放 | 亚洲精品二三区伊人久久 | 91制片厂免费观看 | 精品久久洲久久久久护士免费 | 国产尤物精品视频 | 日本不卡免费新一二三区 | 成年人免费在线看的惊悚动作片 | 国产精品99爱免费视频 | 亚洲国产成人综合 | 欧美老女人b| 欧美一级欧美三级在线 | 国产清纯91天堂在线观看 | 亚洲品质自拍视频 |