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

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

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

服務器之家 - 編程語言 - Java教程 - Spring MVC整合Shiro權限控制的方法

Spring MVC整合Shiro權限控制的方法

2021-04-26 15:26擺碼王子 Java教程

這篇文章主要介紹了Spring MVC整合Shiro權限控制,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

apache shiro 是一個功能強大且靈活的開放源代碼安全框架,可以細粒度地處理認證 (authentication),授權 (authorization),會話 (session) 管理和加密 (cryptography) 等企業級應用中常見的安全控制流程。 apache shiro 的首要目標是易于使用和理解。 有時候安全性的流程控制會非常復雜,對開發人員來說是件很頭疼的事情,但并不一定如此。 框架就應該盡可能地掩蓋復雜性,并公開一個簡潔而直觀的 api,從而簡化開發人員的工作,確保其應用程序安全性。這次我們聊一聊如何在 spring web 應用中使用 shiro 實現權限控制

功能

apache shiro 是一個具有許多功能的綜合型應用程序安全框架。 下圖為 shiro 中的最主要的幾個功能:

 

 
Spring MVC整合Shiro權限控制的方法

 

shiro 的主要目標是“應用安全的四大基石” - 認證,授權,會話管理和加密:

  1. 身份驗證:也就是通常所說的 “登錄”,為了證明用戶的行為所有者。
  2. 授權:訪問控制的過程,即確定什么用戶可以訪問哪些內容。
  3. 會話管理:即使在非 web 應用程序中,也可以管理用戶特定的會話,這也是 shiro 的一大亮點。
  4. 加密技術:使用加密算法保證數據的安全,非常易于使用。

架構

從整體概念上理解,shiro 的體系架構有三個主要的概念:subject (主體,也就是用戶),security manager (安全管理器)和 realms (領域)。 下圖描述了這些組件之間的關系:

 

 
Spring MVC整合Shiro權限控制的方法

 

這幾大組件可以這樣理解:

  1. subject (主體):主體是當前正在操作的用戶的特定數據集合。主體可以是一個人,也可以代表第三方服務,守護進程,定時任務或類似的東西,也就是幾乎所有與該應用進行交互的事物。
  2. security manager (安全管理器):它是 shiro 的體系結構的核心,扮演了類似于一把 “傘” 的角色,它主要負責協調內部的各個組件,形成一張安全網。
  3. realms (領域):shiro 與應用程序安全數據之間的 “橋梁”。當需要實際與用戶帳戶等安全相關數據進行交互以執行認證和授權時,shiro 將從 realms 中獲取這些數據。

數據準備

在 web 應用中,對安全的控制主要有角色、資源、權限(什么角色能訪問什么資源)幾個概念,一個用戶可以有多個角色,一個角色也可以訪問多個資源,也就是角色可以對應多個權限。落實到數據庫設計上,我們至少需要建 5 張表:用戶表、角色表、資源表、角色-資源表、用戶-角色表,這 5 張表的結構如下:

用戶表:

 

id username password
1 張三 123456
2 李四 666666
3 王五 000000

 

角色表:

 

 

id rolename
1 管理員
2 經理
3 員工

 

資源表:

 

id resname
1 /user/add
2 /user/delete
3 /compony/info

 

角色-資源表:

 

id roleid resid
1 1 1
2 1 2
3 2 3

 

用戶-角色表:

 

id userid roleid
1 1 1
2 1 2
3 1 3

 

對應的 pojo 類如下:

?
1
2
3
4
5
6
7
8
9
/**
 * 用戶
 */
public class user {
 private integer id;
 private string username;
 private string password;
 //getter & setter...
}
?
1
2
3
4
5
6
7
/**
 * 角色
 */
public class role {
 private string id;
 private string rolename;
}
?
1
2
3
4
5
6
7
/**
 * 資源
 */
public class resource {
 private string id;
 private string resname;
}
?
1
2
3
4
5
6
7
8
/**
 * 角色-資源
 */
public class roleres {
 private string id;
 private string roleid;
 private string resid;
}
?
1
2
3
4
5
6
7
8
/**
 * 用戶-角色
 */
public class userrole {
 private string id;
 private string userid;
 private string roleid;
}

spring 與 shiro 整合的詳細步驟,請參閱我的博客 《 spring 應用中整合 apache shiro 》 。 這里補充一下:需要提前引入 shiro 的依賴,打開mvnrepository.com,搜索 shiro,我們需要前三個依賴,也就是 shiro-core、shiro-web 以及 shiro-spring,以 maven 項目為例,在 pom.xml 中的 <dependencies> 節點下添加如下依賴:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
 <groupid>org.apache.shiro</groupid>
 <artifactid>shiro-core</artifactid>
 <version>1.4.0</version>
</dependency>
<dependency>
 <groupid>org.apache.shiro</groupid>
 <artifactid>shiro-web</artifactid>
 <version>1.4.0</version>
</dependency>
<dependency>
 <groupid>org.apache.shiro</groupid>
 <artifactid>shiro-spring</artifactid>
 <version>1.4.0</version>
</dependency>

application-context.xml 中需要這樣配置 shirofilter bean:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 配置shiro的過濾器工廠類,id- shirofilter要和我們在web.xml中配置的過濾器一致 -->
<bean id="shirofilter" class="org.apache.shiro.spring.web.shirofilterfactorybean">
 <property name="securitymanager" ref="securitymanager"/>
 <!-- 登錄頁面 -->
 <property name="loginurl" value="/login"/>
 <!-- 登錄成功后的頁面 -->
 <property name="successurl" value="/index"/>
 <!-- 非法訪問跳轉的頁面 -->
 <property name="unauthorizedurl" value="/403"/>
 <!-- 權限配置 -->
 <property name="filterchaindefinitions">
 <value>
  <!-- 無需認證即可訪問的靜態資源,還可以添加其他 url -->
  /static/** = anon
  <!-- 除了上述忽略的資源,其他所有資源都需要認證后才能訪問 -->
  /** = authc
 </value>
 </property>
</bean>

接下來就需要定義 realm 了,自定義的 realm 集成自 authorizingrealm 類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public class myrealm extends authorizingrealm {
 @autowired
 private userservice userservice;
 /**
 * 驗證權限
 */
 @override
 protected authorizationinfo dogetauthorizationinfo(principalcollection principalcollection) {
 string loginname = securityutils.getsubject().getprincipal().tostring();
 if (loginname != null) {
 string userid = securityutils.getsubject().getsession().getattribute("usersessionid").tostring();
 // 權限信息對象,用來存放查出的用戶的所有的角色及權限
 simpleauthorizationinfo info = new simpleauthorizationinfo();
 // 用戶的角色集合
 shirouser shirouser = (shirouser) principalcollection.getprimaryprincipal();
  info.setroles(shirouser.getroles());
  info.addstringpermissions(shirouser.geturlset());
 return info;
 }
 return null;
 }
 /**
 * 認證回調函數,登錄時調用
 */
 protected authenticationinfo dogetauthenticationinfo(authenticationtoken token) {
 string username = (string) token.getprincipal();
 user user = new user();
 sysuser.setusername(username);
 try {
 list<sysuser> users = userservice.findbynames(user);
  list<string> rolelist= userservice.selectrolenamelistbyuserid(users.get(0).getid());
 if (users.size() != 0) {
 string pwd = users.get(0).getpassword();
 // 當驗證都通過后,把用戶信息放在 session 里
 session session = securityutils.getsubject().getsession();
 session.setattribute("usersession", users.get(0));
 session.setattribute("usersessionid", users.get(0).getid());
 session.setattribute("userroles", org.apache.commons.lang.stringutils.join(rolelist,","));
  return new simpleauthenticationinfo(username,users.get(0).getpassword());
 } else {
  // 沒找到該用戶
 throw new unknownaccountexception();
 }
 } catch (exception e) {
 system.out.println(e.getmessage());
 }
 return null;
 }
 /**
 * 更新用戶授權信息緩存.
 */
 public void clearcachedauthorizationinfo(principalcollection principals) {
 super.clearcachedauthorizationinfo(principals);
 }
 /**
 * 更新用戶信息緩存.
 */
 public void clearcachedauthenticationinfo(principalcollection principals) {
 super.clearcachedauthenticationinfo(principals);
 }
 /**
 * 清除用戶授權信息緩存.
 */
 public void clearallcachedauthorizationinfo() {
 getauthorizationcache().clear();
 }
 /**
 * 清除用戶信息緩存.
 */
 public void clearallcachedauthenticationinfo() {
 getauthenticationcache().clear();
 }
 /**
 * 清空所有緩存
 */
 public void clearcache(principalcollection principals) {
 super.clearcache(principals);
 }
 /**
 * 清空所有認證緩存
 */
 public void clearallcache() {
 clearallcachedauthenticationinfo();
 clearallcachedauthorizationinfo();
 }
}

最后定義一個用戶登錄的控制器,接受用戶的登錄請求:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@controller
public class usercontroller {
 /**
 * 用戶登錄
 */
 @postmapping("/login")
 public string login(@valid user user,bindingresult bindingresult,redirectattributes redirectattributes){
 try {
  if(bindingresult.haserrors()){
  return "login";
  }
  //使用權限工具進行認證,登錄成功后跳到 shirofilter bean 中定義的 successurl
  securityutils.getsubject().login(new usernamepasswordtoken(user.getusername(), user.getpassword()));
  return "redirect:index";
 } catch (authenticationexception e) {
  redirectattributes.addflashattribute("message","用戶名或密碼錯誤");
  return "redirect:login";
 }
 }
 /**
 * 注銷登錄
 */
 @getmapping"/logout")
 public string logout(redirectattributes redirectattributes ){
 securityutils.getsubject().logout();
 return "redirect:login";
 }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://juejin.im/post/5abf92b96fb9a028c368ea50

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久综合视频网站 | 日韩色在线观看 | bt岛www| 欧美娇小性xxxx | 日本花季传媒2020旧版安卓 | 亚洲欧美日本在线观看 | 男人和女人全黄一级毛片 | 思敏1一5集国语版免费观看 | 日韩黄色录像 | 日韩视频在线免费观看 | 星星动漫无删减在线观看 | 精品免费国产 | 亚洲精品久久麻豆蜜桃 | 久久久无码精品亚洲欧美 | 亚洲黄网站wwwwww | 日韩精品中文字幕视频一区 | 小柔的性放荡羞辱日记 | 波多野结衣之双方调教在线观看 | 好大好猛好爽好深视频免费 | 国产精品污双胞胎在线观看 | 国产高清ujzzujzz | 深夜在线观看网站 | 天天综合天天影视色香欲俱全 | 91精品国产91久久久久久麻豆 | 欧美高清在线精品一区二区不卡 | 天堂漫画破解版 | 欧美a级v片在线观看一区 | 精品欧美一区二区在线观看欧美熟 | 久久99精品国产免费观看 | 天堂69亚洲精品中文字幕 | 男人操女人视频 | 古装床戏做爰无遮挡三级 | 亚洲精品中文字幕第一区 | 欧美一区二区福利视频 | 免费特黄一区二区三区视频一 | 隔壁老王国产精品福利 | 日产乱码卡一卡2卡三卡四福利 | 日本美女视频韩国视频网站免费 | 国产a免费观看 | 免费看黄色大片 | 韩国情事伦理片观看地址 |