小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

JAVAWEB開發(fā)之權(quán)限管理(一)

 hkls0003 2018-08-03

知識清單

1.了解基于資源的權(quán)限管理方式
2. 掌握權(quán)限數(shù)據(jù)模型
3. 掌握基于url的權(quán)限管理(不使用Shiro權(quán)限框架的情況下實現(xiàn)權(quán)限管理)
4. shiro實現(xiàn)用戶認證
5. shiro實現(xiàn)用戶授權(quán)
6. shiro與企業(yè)web項目整合開發(fā)的方法

權(quán)限管理原理知識

什么是權(quán)限管理

只要有用戶參與的系統(tǒng)一般都要有權(quán)限管理,權(quán)限管理實現(xiàn)對用戶訪問系統(tǒng)的控制。按照安全規(guī)則或安全策略控制用戶可以訪問而且只能訪問自己被授權(quán)的資源。
權(quán)限管理包括用戶認證和用戶授權(quán)兩部分。

用戶認證

用戶認證概念

用戶認證—— 用戶去訪問系統(tǒng),系統(tǒng)需要驗證用戶身份的合法性。最常用的用戶身份認證方法:1.用戶密碼方式、2.指紋打卡機、3.基于證書的驗證方法。系統(tǒng)驗證用戶身份合法,用戶方可訪問系統(tǒng)的資源。

用戶認證流程


關(guān)鍵對象

subject:主體,理解為用戶,可能是程序,都要去訪問系統(tǒng)的資源,系統(tǒng)需要對subject進行身份認證。
principal:身份信息,通常是唯一的,一個主體可以有多個身份信息,但是只能有一個主身份信息(primary  principal)。
credential:憑證信息,可以是密碼、證書、指紋等。
總結(jié):主體在進行身份認證時需要提供身份信息和憑證信息。

用戶授權(quán)

用戶授權(quán)概念

用戶授權(quán),簡單理解為訪問控制,在用戶認證通過后,系統(tǒng)對用戶訪問資源進行控制,當用戶具有資源的訪問權(quán)限方可訪問。

授權(quán)流程


其中橙色為授權(quán)流程

關(guān)鍵對象

授權(quán)的過程可以理解為  who  對 what(which) 進行how操作
who:主體,即subject,subject在認證通過后,系統(tǒng)進行訪問控制。
what(which):資源(Resource) ,subject必須具備資源訪問權(quán)限才可以訪問該資源。資源包括很多方面比如:用戶列表頁面、商品修改菜單、商品id為001的商品信息。
資源分為資源類型和資源實例
例如系統(tǒng)的用戶信息就是資源類型,相當于Java類。
系統(tǒng)中id為001的用戶就是資源實例,相當于new的Java對象。
how:權(quán)限/許可(permission),針對資源的權(quán)限或許可,subject必須具有permission方可訪問資源,如何訪問/操作需要定義permission,權(quán)限比如:用戶添加、用戶添加、商品刪除。

權(quán)限模型

主體(賬號、密碼)
資源(資源名稱,訪問地址)
權(quán)限(權(quán)限名稱、資源id)
角色(角色名稱)
角色和權(quán)限關(guān)系(角色id、權(quán)限id)
如下圖:

通常企業(yè)開發(fā)中將資源和權(quán)限合并為一張權(quán)限表,如下:
資源(資源名稱、訪問地址)
權(quán)限(權(quán)限名稱、資源id)
合并為:
權(quán)限(權(quán)限名稱、資源名稱、資源訪問地址)

上圖被稱為權(quán)限管理的通用模型,不過在企業(yè)開發(fā)中根據(jù)系統(tǒng)自身特點還會對上圖進行修改,但是用戶、角色、權(quán)限、用戶角色關(guān)系、角色權(quán)限關(guān)系是必不可少的。

分配權(quán)限

用戶需要分配相應的權(quán)限才可以訪問相應的資源。權(quán)限是對資源的操作許可。
通常給用戶分配資源權(quán)限需要將權(quán)限信息持久化,比如存儲在關(guān)系數(shù)據(jù)庫中。
把用戶信息、權(quán)限管理、用戶分配的權(quán)限信息寫入到數(shù)據(jù)庫(權(quán)限數(shù)據(jù)模型)。

權(quán)限控制(授權(quán)核心)

基于角色的訪問控制

RBAC (Role  based access  control) 基于角色的訪問控制
比如:
系統(tǒng)角色包括:部門經(jīng)理、總經(jīng)理...(角色針對用戶進行劃分)
系統(tǒng)中代碼實現(xiàn):
//如果該user是部門經(jīng)理則可以訪問if中的代碼
if(user.getRole("部門經(jīng)理")){
    // 系統(tǒng)資源內(nèi)容
    // 用戶報表查看
}
問題:
角色是針對人進行劃分的,人作為用戶在系統(tǒng)中屬于活動內(nèi)容,如果該角色可以訪問的資源出現(xiàn)變更,則需要修改代碼,比如:需要變更為部門經(jīng)理和總經(jīng)理都可以進行用戶報表查看,代碼改為:
if(user.getRole("部門經(jīng)理") || user.getRole("總經(jīng)理")){
    // 系統(tǒng)資源內(nèi)容
    // 用戶報表查看
}
由此可以發(fā)現(xiàn)基于角色的訪問控制是不利于系統(tǒng)維護的(可擴展性不強)

基于資源的訪問控制

RBAC (Resource  based  access control)  基于資源的訪問控制
資源在系統(tǒng)中是不變的,比如資源有:類中的方法,頁面中的按鈕
對資源的訪問需要具有permission權(quán)限,代碼可以寫為:
if(user.hasPermission("用戶報表查看(權(quán)限標識符)")){
    // 系統(tǒng)資源內(nèi)容
    // 用戶報表查看
}
上面的方法就可以解決用戶角色變更而不用修改上邊權(quán)限控制的代碼。
如果需要變更權(quán)限只需要在分配權(quán)限模塊去操作,給部門經(jīng)理或總經(jīng)理增加或解除權(quán)限
建議使用基于資源的訪問控制實現(xiàn)權(quán)限管理。

權(quán)限管理解決方案

什么是粗粒度權(quán)限和細粒度權(quán)限?

粗粒度權(quán)限管理,是對資源類型的管理,資源類型比如:菜單、url連接、用戶添加頁面、用戶信息、類方法、頁面中按鈕。
粗粒度權(quán)限管理比如:超級管理員可以訪問用戶添加頁面、用戶信息等全部頁面。
部門管理員可以訪問用戶信息頁面,包括頁面中所有按鈕。

細粒度的權(quán)限管理,對資源實例的權(quán)限管理。資源實例就是資源類型的具體化,比如:用戶id為001的修改連接,1110班的用戶信息、行政部的員工。
細粒度的權(quán)限管理就是數(shù)據(jù)級別的權(quán)限管理。
細粒度權(quán)限管理比如:部門經(jīng)理只可以訪問本部門的員工信息,用戶只可以看到自己的菜單,大區(qū)經(jīng)理只能查看本轄區(qū)的銷售訂單...

粗粒度和細粒度例子:
系統(tǒng)中有一個用戶查詢頁面,對用戶列表查詢分權(quán)限,如粗粒度管理,張三和李四都有用戶列表查詢的權(quán)限,張三和李四都可以訪問用戶列表查詢。
進一步進行細粒度的管理,張三(行政部)和李四(開發(fā)部)只可以查詢自己本部門的用戶信息,張三只能查看行政部的用戶信息,李四只能查詢開發(fā)部門的用戶信息。細粒度的權(quán)限管理就是數(shù)據(jù)級別的權(quán)限管理。

如何實現(xiàn)粗粒度和細粒度的權(quán)限管理

如何實現(xiàn)粗粒度的權(quán)限管理?
粗粒度權(quán)限管理比較容易將權(quán)限管理代碼抽取出來在系統(tǒng)架構(gòu)級別統(tǒng)一管理。比如:通過SpringMVC的攔截器實現(xiàn)授權(quán)。
如何實現(xiàn)細粒度的權(quán)限管理?
對細粒度的權(quán)限管理在數(shù)據(jù)級別是沒有共性可言的,針對細粒度的權(quán)限管理就是系統(tǒng)業(yè)務邏輯的一部分,如果在業(yè)務層去處理相對簡單,如果將細粒度的權(quán)限管理統(tǒng)一在系統(tǒng)架構(gòu)級別去抽取,比較困難,即使進行了抽取,功能也可能存在擴展性不全的弊端。建議細粒度權(quán)限管理放在業(yè)務層去控制。比如:部門經(jīng)理只查詢本部門員工信息,在Service接口提供一個部門id的參數(shù),controller中根據(jù)當前用戶信息得到該用戶屬于哪個部門,調(diào)用service時將部門id傳入service,實現(xiàn)該用戶只查詢本部門的員工。

基于url攔截的方式實現(xiàn)

基于url攔截的方式實現(xiàn)在實際開發(fā)中是比較常用的一種方式。
對于web系統(tǒng),通過filter過濾器實現(xiàn)url攔截,也可以通過SpringMVC的攔截器實現(xiàn)基于URL的攔截。

使用權(quán)限管理框架來實現(xiàn)

對于粗粒度的權(quán)限管理,建議使用優(yōu)秀的權(quán)限管理框架進行實現(xiàn),節(jié)省開發(fā)成本,提高開發(fā)效率。
Shiro就是一個優(yōu)秀的權(quán)限管理框架。

基于URL的權(quán)限管理

基于url的權(quán)限管理流程



搭建環(huán)境

數(shù)據(jù)庫

MySQL數(shù)據(jù)庫中創(chuàng)建表:用戶表、角色表、權(quán)限表(實質(zhì)是權(quán)限和資源的結(jié)合)、用戶角色關(guān)系表、角色權(quán)限關(guān)系表

新建數(shù)據(jù)庫shiro, 為了節(jié)約測試時間,在SpringMVC+mybatis基礎之上進行整合(導入以前的基本數(shù)據(jù)),并導入權(quán)限數(shù)據(jù)如下:

有關(guān)權(quán)限的SQL腳本如下:
shiro_sql_table.sql
  1. /*
  2. SQLyog v10.2
  3. MySQL - 5.1.72-community : Database - shiro
  4. *********************************************************************
  5. */
  6. /*!40101 SET NAMES utf8 */;
  7. /*!40101 SET SQL_MODE=''*/;
  8. /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
  9. /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
  10. /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
  11. /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
  12. /*Table structure for table `sys_permission` */
  13. CREATE TABLE `sys_permission` (
  14. `id` bigint(20) NOT NULL COMMENT '主鍵',
  15. `name` varchar(128) NOT NULL COMMENT '資源名稱',
  16. `type` varchar(32) NOT NULL COMMENT '資源類型:menu,button,',
  17. `url` varchar(128) DEFAULT NULL COMMENT '訪問url地址',
  18. `percode` varchar(128) DEFAULT NULL COMMENT '權(quán)限代碼字符串',
  19. `parentid` bigint(20) DEFAULT NULL COMMENT '父結(jié)點id',
  20. `parentids` varchar(128) DEFAULT NULL COMMENT '父結(jié)點id列表串',
  21. `sortstring` varchar(128) DEFAULT NULL COMMENT '排序號',
  22. `available` char(1) DEFAULT NULL COMMENT '是否可用,1:可用,0不可用',
  23. PRIMARY KEY (`id`)
  24. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  25. /*Table structure for table `sys_role` */
  26. CREATE TABLE `sys_role` (
  27. `id` varchar(36) NOT NULL,
  28. `name` varchar(128) NOT NULL,
  29. `available` char(1) DEFAULT NULL COMMENT '是否可用,1:可用,0不可用',
  30. PRIMARY KEY (`id`)
  31. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  32. /*Table structure for table `sys_role_permission` */
  33. CREATE TABLE `sys_role_permission` (
  34. `id` varchar(36) NOT NULL,
  35. `sys_role_id` varchar(32) NOT NULL COMMENT '角色id',
  36. `sys_permission_id` varchar(32) NOT NULL COMMENT '權(quán)限id',
  37. PRIMARY KEY (`id`)
  38. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  39. /*Table structure for table `sys_user` */
  40. CREATE TABLE `sys_user` (
  41. `id` varchar(36) NOT NULL COMMENT '主鍵',
  42. `usercode` varchar(32) NOT NULL COMMENT '賬號',
  43. `username` varchar(64) NOT NULL COMMENT '姓名',
  44. `password` varchar(32) NOT NULL COMMENT '密碼',
  45. `salt` varchar(64) DEFAULT NULL COMMENT '鹽',
  46. `locked` char(1) DEFAULT NULL COMMENT '賬號是否鎖定,1:鎖定,0未鎖定',
  47. PRIMARY KEY (`id`)
  48. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  49. /*Table structure for table `sys_user_role` */
  50. CREATE TABLE `sys_user_role` (
  51. `id` varchar(36) NOT NULL,
  52. `sys_user_id` varchar(32) NOT NULL,
  53. `sys_role_id` varchar(32) NOT NULL,
  54. PRIMARY KEY (`id`)
  55. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  56. /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
  57. /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
  58. /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
  59. /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
shiro_sql_table_data.sql
  1. /*
  2. SQLyog v10.2
  3. MySQL - 5.1.72-community : Database - shiro
  4. *********************************************************************
  5. */
  6. /*!40101 SET NAMES utf8 */;
  7. /*!40101 SET SQL_MODE=''*/;
  8. /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
  9. /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
  10. /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
  11. /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
  12. /*Data for the table `sys_permission` */
  13. insert into `sys_permission`(`id`,`name`,`type`,`url`,`percode`,`parentid`,`parentids`,`sortstring`,`available`) values
  14. (1,'權(quán)限','','',NULL,0,'0/','0','1'),(11,'商品管理','menu','/item/queryItem.action',NULL,1,'0/1/','1.','1'),
  15. (12,'商品新增','permission','/item/add.action','item:create',11,'0/1/11/','','1'),
  16. (13,'商品修改','permission','/item/editItem.action','item:update',11,'0/1/11/','','1'),
  17. (14,'商品刪除','permission','','item:delete',11,'0/1/11/','','1'),
  18. (15,'商品查詢','permission','/item/queryItem.action','item:query',11,'0/1/15/',NULL,'1'),
  19. (21,'用戶管理','menu','/user/query.action','user:query',1,'0/1/','2.','1'),
  20. (22,'用戶新增','permission','','user:create',21,'0/1/21/','','1'),
  21. (23,'用戶修改','permission','','user:update',21,'0/1/21/','','1'),
  22. (24,'用戶刪除','permission','','user:delete',21,'0/1/21/','','1');
  23. /*Data for the table `sys_role` */
  24. insert into `sys_role`(`id`,`name`,`available`) values
  25. ('ebc8a441-c6f9-11e4-b137-0adc305c3f28','商品管理員','1'),
  26. ('ebc9d647-c6f9-11e4-b137-0adc305c3f28','用戶管理員','1');
  27. /*Data for the table `sys_role_permission` */
  28. insert into `sys_role_permission`(`id`,`sys_role_id`,`sys_permission_id`) values
  29. ('ebc8a441-c6f9-11e4-b137-0adc305c3f21','ebc8a441-c6f9-11e4-b137-0adc305c','12'),
  30. ('ebc8a441-c6f9-11e4-b137-0adc305c3f22','ebc8a441-c6f9-11e4-b137-0adc305c','11'),
  31. ('ebc8a441-c6f9-11e4-b137-0adc305c3f24','ebc9d647-c6f9-11e4-b137-0adc305c','21'),
  32. ('ebc8a441-c6f9-11e4-b137-0adc305c3f25','ebc8a441-c6f9-11e4-b137-0adc305c','15'),
  33. ('ebc9d647-c6f9-11e4-b137-0adc305c3f23','ebc9d647-c6f9-11e4-b137-0adc305c','22'),
  34. ('ebc9d647-c6f9-11e4-b137-0adc305c3f26','ebc8a441-c6f9-11e4-b137-0adc305c','13');
  35. /*Data for the table `sys_user` */
  36. insert into `sys_user`(`id`,`usercode`,`username`,`password`,`salt`,`locked`) values
  37. ('lisi','lisi','李四','bf07fd8bbc73b6f70b8319f2ebb87483','uiwueylm','0'),
  38. ('zhangsan','zhangsan','張三','cb571f7bd7a6f73ab004a70322b963d5','eteokues','0');
  39. /*Data for the table `sys_user_role` */
  40. insert into `sys_user_role`(`id`,`sys_user_id`,`sys_role_id`) values
  41. ('ebc8a441-c6f9-11e4-b137-0adc305c3f28','zhangsan','ebc8a441-c6f9-11e4-b137-0adc305c'),
  42. ('ebc9d647-c6f9-11e4-b137-0adc305c3f28','lisi','ebc9d647-c6f9-11e4-b137-0adc305c');
  43. /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
  44. /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
  45. /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
  46. /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
查看對應權(quán)限模型的數(shù)據(jù)如下:
sys_user  用戶表數(shù)據(jù)

sys_role  角色表

sys_permission 權(quán)限表

sys_user_role  用戶角色關(guān)系表

sys_role_permission  角色權(quán)限關(guān)系表

開發(fā)環(huán)境

JDK1.8
MyEclipse
技術(shù)架構(gòu):SpringMVC+Mybatis+jQuery easyUI

系統(tǒng)工程架構(gòu)


系統(tǒng)登錄

系統(tǒng)登錄相當于用戶身份認證,用戶登錄成功,要在Session中記錄用戶的身份信息。
操作流程:
用戶進入登錄頁面。
輸入用戶名和密碼進行登陸。
進行用戶名和密碼校驗。
如果校驗通過,在Session中記錄用戶身份信息。

用戶的身份信息

創(chuàng)建專門類用于記錄用戶身份信息。
  1. /**
  2. * 用戶身份信息,存入Session 由于Tomcat正常關(guān)閉時會將Session序列化的本地硬盤上,所以實現(xiàn)Serializable接口
  3. * @author liuxun
  4. *
  5. */
  6. public class ActiveUser implements Serializable {
  7. private String userid; //用戶id(主鍵)
  8. private String usercode; // 用戶賬號
  9. private String username; // 用戶姓名
  10. ....
  11. ....
  12. }

mapper

mapper接口:根據(jù)用戶賬號查詢用戶(sys_user)信息 (使用逆向工程生成權(quán)限相關(guān)的PO類和mapper接口)
如下所示:
  
將生成的代碼拷貝到項目中

service(進行用戶名和密碼校驗)

接口功能:根據(jù)用戶的身份和密碼進行認證,如果認證通過,返回用戶身份信息。
認證過程:
根據(jù)用戶身份(賬號)查詢數(shù)據(jù)庫,如果查詢不到 則拋出用戶不存在
對輸入的密碼和數(shù)據(jù)庫密碼進行比對,如果一致,認證通過。
新建權(quán)限管理Service接口 添加身份認證方法
  1. /**
  2. * 認證授權(quán)服務接口
  3. * @author liuxun
  4. *
  5. */
  6. public interface SysService {
  7. //根據(jù)用戶的身份和密碼進行認證,如果認證通過,返回用戶身份信息
  8. public ActiveUser authenticat(String usercode,String password) throws Exception;
  9. //根據(jù)用戶賬號查詢用戶信息
  10. public SysUser findSysUserByUserCode(String userCode) throws Exception;
  11. ......
  12. }
方法實現(xiàn):
  1. public class SysServiceImpl implements SysService {
  2. @Autowired
  3. private SysUserMapper sysUserMapper;
  4. public ActiveUser authenticat(String usercode, String password) throws Exception {
  5. /**
  6. * 認證過程: 根據(jù)用戶身份(賬號)查詢數(shù)據(jù)庫,如果查詢不到則用戶不存在
  7. * 對輸入的密碼和數(shù)據(jù)庫密碼進行比對,如果一致則認證通過
  8. */
  9. // 根據(jù)用戶賬號查詢數(shù)據(jù)庫
  10. SysUser sysUser = this.findSysUserByUserCode(usercode);
  11. if (sysUser == null) {
  12. // 拋出異常
  13. throw new CustomException("用戶賬號不存在");
  14. }
  15. // 數(shù)據(jù)庫密碼(MD5加密后的密碼)
  16. String password_db = sysUser.getPassword();
  17. // 對輸入的密碼和數(shù)據(jù)庫密碼進行比對,如果一致,認證通過
  18. // 對頁面輸入的密碼進行MD5加密
  19. String password_input_md5 = new MD5().getMD5ofStr(password);
  20. if (!password_db.equalsIgnoreCase(password_input_md5)) {
  21. //拋出異常
  22. throw new CustomException("用戶名或密碼錯誤");
  23. }
  24. //得到用戶id
  25. String userid = sysUser.getId();
  26. //認證通過,返回用戶身份信息
  27. ActiveUser activeUser = new ActiveUser();
  28. activeUser.setUserid(userid);
  29. activeUser.setUsercode(usercode);
  30. activeUser.setUsername(sysUser.getUsername());
  31. return activeUser;
  32. }
  33. public SysUser findSysUserByUserCode(String userCode) throws Exception {
  34. SysUserExample sysUserExample = new SysUserExample();
  35. SysUserExample.Criteria criteria = sysUserExample.createCriteria();
  36. criteria.andUsercodeEqualTo(userCode);
  37. List<SysUser> list = sysUserMapper.selectByExample(sysUserExample);
  38. if (list != null && list.size() > 0) {
  39. return list.get(0);
  40. }
  41. return null;
  42. }
  43. ......
  44. }
配置Service,往類Service中使用@Autowire 需要注冊Service 注冊有兩種方法(注解或配置文件),在架構(gòu)時沒有配置掃描Service  需要在配置文件中注冊Service
  1. <!-- 認證和授權(quán)的Service -->
  2. <bean id="sysService" class="liuxun.ssm.service.impl.SysServiceImpl"></bean>

controller(記錄Session)

  1. //用戶登錄提交方法
  2. @RequestMapping("/login")
  3. public String login(HttpSession session,String randomcode,String usercode,String password) throws Exception{
  4. // 校驗驗證碼,防止惡性攻擊
  5. // 從Session中獲取正確的驗證碼
  6. String validateCode = (String) session.getAttribute("validateCode");
  7. //輸入的驗證碼和Session中的驗證碼進行對比
  8. if (!randomcode.equalsIgnoreCase(validateCode)) {
  9. //拋出異常
  10. throw new CustomException("驗證碼輸入錯誤");
  11. }
  12. //調(diào)用Service校驗用戶賬號和密碼的正確性
  13. ActiveUser activeUser = sysService.authenticat(usercode, password);
  14. //如果Service校驗通過,將用戶身份記錄到Session
  15. session.setAttribute("activeUser", activeUser);
  16. //重定向到商品查詢頁面
  17. return "redirect:/first.action";
  18. }

用戶認證攔截器

anonymousURL.properties配置匿名URL

配置可以匿名訪問的URL


編寫身份認證攔截器

  1. //用于用戶認證校驗、用戶權(quán)限校驗
  2. @Override
  3. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  4. //得到請求的url
  5. String url = request.getRequestURI();
  6. //判斷是否是公開地址
  7. //實際開發(fā)中需要將公開地址配置在配置文件中
  8. //從配置文件中取出可以匿名訪問的URL
  9. List<String> open_urls = ResourcesUtil.getKeyList("anonymousURL");
  10. for (String open_url : open_urls) {
  11. if (url.indexOf(open_url)>=0) {
  12. //如果是公開地址 則放行
  13. return true;
  14. }
  15. }
  16. //判斷用戶身份在Session中是否存在
  17. HttpSession session = request.getSession();
  18. ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
  19. //如果用戶身份在session中存在則放行
  20. if (activeUser!=null) {
  21. return true;
  22. }
  23. //執(zhí)行到這里攔截,跳轉(zhuǎn)到登錄頁面,用戶進行身份認證
  24. request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
  25. //如果返回false表示攔截器不繼續(xù)執(zhí)行handler,如果返回true表示放行
  26. return false;
  27. }

配置認證攔截器

  1. <!-- 攔截器 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <!-- 用戶認證攔截 -->
  5. <mvc:mapping path="/**"/>
  6. <bean class="liuxun.ssm.controller.interceptor.LoginInterceptor"></bean>
  7. </mvc:interceptor>
  8. </mvc:interceptors>

用戶授權(quán)

commonURL.properties配置公用訪問地址

在此配置文件中配置公用訪問地址,公用訪問地址只需要通過用戶認證,不需要對公用訪問地址分配權(quán)限即可訪問。

獲取用戶權(quán)限范圍的菜單

思路:
在用戶認證時,認證通過,根據(jù)用戶id從數(shù)據(jù)庫獲取用戶權(quán)限范圍內(nèi)的菜單,將菜單的集合存儲在Session中。
編輯存儲用戶身份信息的類ActiveUser 如下所示:
  1. public class ActiveUser implements Serializable {
  2. private String userid; //用戶id(主鍵)
  3. private String usercode; // 用戶賬號
  4. private String username; // 用戶姓名
  5. private List<SysPermission> menus; //菜單
  6. //......setter和getter方法
  7. }
自定義權(quán)限Mapper
因為使用逆向工程生成的Mapper是不建議去修改的 因為它的代碼聯(lián)系非常緊密,一旦修改錯誤 就會牽一發(fā)而動全身。所以需要自定義一個權(quán)限的Mapper(SysPermissionMapperCustom)
在SysPermissionMapperCustom.xml中添加根據(jù)用戶id查詢用戶權(quán)限的菜單
  1. <!-- 根據(jù)用戶id查詢菜單 -->
  2. <select id="findMenuListByUserId" parameterType="string" resultType="liuxun.ssm.po.SysPermission">
  3. SELECT
  4. *
  5. FROM
  6. sys_permission
  7. WHERE TYPE = 'menu'
  8. AND id IN
  9. (SELECT
  10. sys_permission_id
  11. FROM
  12. sys_role_permission
  13. WHERE sys_role_id IN
  14. (SELECT
  15. sys_role_id
  16. FROM
  17. sys_user_role
  18. WHERE sys_user_id = #{userid}))
  19. </select>
在SysPermissionMapperCustom.java接口中添加對應的方法
  1. public interface SysPermissionMapperCustom {
  2. //根據(jù)用戶id查詢菜單
  3. public List<SysPermission> findMenuListByUserId(String userid) throws Exception;
  4. .......
  5. }
在權(quán)限Service接口中添加對應的方法 在實現(xiàn)中注入SysPermissionMapperCustom
SysServiceImpl.java中添加如下內(nèi)容
  1. @Override
  2. public List<SysPermission> findMenuListByUserId(String userid) throws Exception {
  3. return sysPermissionMapperCustom.findMenuListByUserId(userid);
  4. }

獲取用戶權(quán)限范圍的URL

思路:
在用戶認證時,認證通過后,根據(jù)用戶id從數(shù)據(jù)庫中獲取用戶權(quán)限范圍的URL,將URL的集合存儲在Session中。
修改ActiveUser 添加URL的權(quán)限集合
  1. public class ActiveUser implements Serializable {
  2. private String userid; //用戶id(主鍵)
  3. private String usercode; // 用戶賬號
  4. private String username; // 用戶姓名
  5. private List<SysPermission> menus; //菜單
  6. private List<SysPermission> permissions; //權(quán)限
  7. //...setter和getter方法
  8. }
在SysPermissionMapperCustom.xml中添加根據(jù)用戶id查詢用戶權(quán)限的URL
  1. <!-- 根據(jù)用戶id查詢URL -->
  2. <select id="findPermissionListByUserId" parameterType="string" resultType="liuxun.ssm.po.SysPermission">
  3. SELECT
  4. *
  5. FROM
  6. sys_permission
  7. WHERE TYPE = 'permission'
  8. AND id IN
  9. (SELECT
  10. sys_permission_id
  11. FROM
  12. sys_role_permission
  13. WHERE sys_role_id IN
  14. (SELECT
  15. sys_role_id
  16. FROM
  17. sys_user_role
  18. WHERE sys_user_id = #{userid}))
  19. </select>
在SysPermissionMapperCustom.java接口中添加對應的方法
  1. //根據(jù)用戶id查詢權(quán)限URL
  2. public List<SysPermission> findPermissionListByUserId(String userid) throws Exception;
SysServiceImpl.java中添加如下內(nèi)容
  1. @Override
  2. public List<SysPermission> findPermissionListByUserId(String userid) throws Exception {
  3. return sysPermissionMapperCustom.findPermissionListByUserId(userid);
  4. }

用戶認證通過后取出菜單和URL放入Session

修改權(quán)限SysServiceImpl中用戶認證方法的代碼
  1. //得到用戶id
  2. String userid = sysUser.getId();
  3. //根據(jù)用戶id查詢菜單
  4. List<SysPermission> menus = this.findMenuListByUserId(userid);
  5. //根據(jù)用戶id查詢權(quán)限url
  6. List<SysPermission> permissions = this.findPermissionListByUserId(userid);
  7. //認證通過,返回用戶身份信息
  8. ActiveUser activeUser = new ActiveUser();
  9. activeUser.setUserid(userid);
  10. activeUser.setUsercode(usercode);
  11. activeUser.setUsername(sysUser.getUsername());
  12. //放入權(quán)限范圍的菜單和url
  13. activeUser.setMenus(menus);
  14. activeUser.setPermissions(permissions);

菜單動態(tài)顯示

  1. <c:if test="${activeUser.menus!=null }">
  2. <ul>
  3. <c:forEach items="${activeUser.menus }" var="menu">
  4. <li><div>
  5. <a title="${menu.name }" ref="1_1" href="#"
  6. rel="${baseurl }/${menu.url }" icon="icon-log"><span
  7. class="icon icon-log"> </span><span class="nav"><a href=javascript:addTab('${menu.name }','${baseurl }/${menu.url }')>${menu.name }</a></span></a>
  8. </div></li>
  9. </c:forEach>
  10. </ul>
  11. </c:if>

授權(quán)攔截器

  1. public class PermissionInterceptor implements HandlerInterceptor{
  2. //在執(zhí)行handler之前執(zhí)行的
  3. //用于用戶認證校驗、用戶權(quán)限校驗
  4. @Override
  5. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  6. //得到請求的url
  7. String url = request.getRequestURI();
  8. //判斷是否是公開地址
  9. //實際開發(fā)中需要將公開地址配置在配置文件中
  10. //從配置文件中取出可以匿名訪問的URL
  11. List<String> open_urls = ResourcesUtil.getKeyList("anonymousURL");
  12. for (String open_url : open_urls) {
  13. if (url.indexOf(open_url)>=0) {
  14. //如果是公開地址 則放行
  15. return true;
  16. }
  17. }
  18. //從配置文件中獲取公用訪問url
  19. List<String> common_urls = ResourcesUtil.getKeyList("commonURL");
  20. //遍歷公用地址 如果是公開地址則放行
  21. for (String common_url : common_urls) {
  22. if (url.indexOf(common_url)>0) {
  23. //如果是公開,則放行
  24. return true;
  25. }
  26. }
  27. //判斷用戶身份在Session中是否存在
  28. HttpSession session = request.getSession();
  29. ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
  30. //從Session中取出權(quán)限范圍的URL
  31. List<SysPermission> permissions = activeUser.getPermissions();
  32. for (SysPermission sysPermission : permissions) {
  33. //權(quán)限url
  34. String permission_url = sysPermission.getUrl();
  35. if (url.indexOf(permission_url)>0) {
  36. return true;
  37. }
  38. }
  39. //執(zhí)行到這里攔截,跳轉(zhuǎn)到無權(quán)訪問的提示頁面
  40. request.getRequestDispatcher("/WEB-INF/jsp/refuse.jsp").forward(request, response);
  41. //如果返回false表示攔截器不繼續(xù)執(zhí)行handler,如果返回true表示放行
  42. return false;
  43. }
  44. ......
  45. }

配置授權(quán)攔截器

注意:要將授權(quán)攔截器配置在用戶認證攔截器的下邊,這是因為SpringMVC攔截器的放行方法是順序執(zhí)行的,如果是Struts的話則正好相反。
  1. <!-- 攔截器 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <!-- 用戶認證攔截 -->
  5. <mvc:mapping path="/**"/>
  6. <bean class="liuxun.ssm.controller.interceptor.LoginInterceptor"></bean>
  7. </mvc:interceptor>
  8. <mvc:interceptor>
  9. <!-- 資源攔截 -->
  10. <mvc:mapping path="/**"/>
  11. <bean class="liuxun.ssm.controller.interceptor.PermissionInterceptor"></bean>
  12. </mvc:interceptor>
  13. </mvc:interceptors>
運行測試:
其關(guān)鍵代碼如下:
PO類ActiveUser.java 存放用戶身份和權(quán)限信息的類
  1. package liuxun.ssm.po;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. /**
  5. * 用戶身份信息,存入Session 由于Tomcat正常關(guān)閉時會將Session序列化的本地硬盤上,所以實現(xiàn)Serializable接口
  6. * @author liuxun
  7. *
  8. */
  9. public class ActiveUser implements Serializable {
  10. private static final long serialVersionUID = 1L;
  11. private String userid; //用戶id(主鍵)
  12. private String usercode; // 用戶賬號
  13. private String username; // 用戶姓名
  14. private List<SysPermission> menus; //菜單
  15. private List<SysPermission> permissions; //權(quán)限
  16. // 提供對應setter和getter方法
  17. ......
  18. }
自定義權(quán)限的Mapper 
SysPermissionMapperCustom.java
  1. package liuxun.ssm.mapper;
  2. import java.util.List;
  3. import liuxun.ssm.po.SysPermission;
  4. import liuxun.ssm.po.SysPermissionExample;
  5. import org.apache.ibatis.annotations.Param;
  6. /**
  7. * 權(quán)限mapper
  8. * @author liuxun
  9. *
  10. */
  11. public interface SysPermissionMapperCustom {
  12. //根據(jù)用戶id查詢菜單
  13. public List<SysPermission> findMenuListByUserId(String userid) throws Exception;
  14. //根據(jù)用戶id查詢權(quán)限URL
  15. public List<SysPermission> findPermissionListByUserId(String userid) throws Exception;
  16. }
SysPermissionMapperCustom.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "http:///dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="liuxun.ssm.mapper.SysPermissionMapperCustom">
  4. <!-- 根據(jù)用戶id查詢菜單 -->
  5. <select id="findMenuListByUserId" parameterType="string" resultType="liuxun.ssm.po.SysPermission">
  6. SELECT
  7. *
  8. FROM
  9. sys_permission
  10. WHERE TYPE = 'menu'
  11. AND id IN
  12. (SELECT
  13. sys_permission_id
  14. FROM
  15. sys_role_permission
  16. WHERE sys_role_id IN
  17. (SELECT
  18. sys_role_id
  19. FROM
  20. sys_user_role
  21. WHERE sys_user_id = #{userid}))
  22. </select>
  23. <!-- 根據(jù)用戶id查詢URL -->
  24. <select id="findPermissionListByUserId" parameterType="string" resultType="liuxun.ssm.po.SysPermission">
  25. SELECT
  26. *
  27. FROM
  28. sys_permission
  29. WHERE TYPE = 'permission'
  30. AND id IN
  31. (SELECT
  32. sys_permission_id
  33. FROM
  34. sys_role_permission
  35. WHERE sys_role_id IN
  36. (SELECT
  37. sys_role_id
  38. FROM
  39. sys_user_role
  40. WHERE sys_user_id = #{userid}))
  41. </select>
  42. </mapper>
自定義權(quán)限的Service接口以及實現(xiàn)類
SysService.java
  1. package liuxun.ssm.service;
  2. import java.util.List;
  3. import liuxun.ssm.po.ActiveUser;
  4. import liuxun.ssm.po.SysPermission;
  5. import liuxun.ssm.po.SysUser;
  6. /**
  7. * 認證授權(quán)服務接口
  8. * @author liuxun
  9. *
  10. */
  11. public interface SysService {
  12. //根據(jù)用戶的身份和密碼進行認證,如果認證通過,返回用戶身份信息
  13. public ActiveUser authenticat(String usercode,String password) throws Exception;
  14. //根據(jù)用戶賬號查詢用戶信息
  15. public SysUser findSysUserByUserCode(String userCode) throws Exception;
  16. //根據(jù)用戶id查詢權(quán)限范圍內(nèi)的菜單
  17. public List<SysPermission> findMenuListByUserId(String userid) throws Exception;
  18. //根據(jù)用戶id查詢權(quán)限范圍內(nèi)的url
  19. public List<SysPermission> findPermissionListByUserId(String userid) throws Exception;
  20. }
SysServiceImpl.java
  1. package liuxun.ssm.service.impl;
  2. import java.util.List;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import liuxun.ssm.exception.CustomException;
  5. import liuxun.ssm.mapper.SysPermissionMapperCustom;
  6. import liuxun.ssm.mapper.SysUserMapper;
  7. import liuxun.ssm.po.ActiveUser;
  8. import liuxun.ssm.po.SysPermission;
  9. import liuxun.ssm.po.SysUser;
  10. import liuxun.ssm.po.SysUserExample;
  11. import liuxun.ssm.service.SysService;
  12. import liuxun.ssm.util.MD5;
  13. public class SysServiceImpl implements SysService {
  14. @Autowired
  15. private SysUserMapper sysUserMapper;
  16. @Autowired
  17. private SysPermissionMapperCustom sysPermissionMapperCustom;
  18. public ActiveUser authenticat(String usercode, String password) throws Exception {
  19. /**
  20. * 認證過程: 根據(jù)用戶身份(賬號)查詢數(shù)據(jù)庫,如果查詢不到則用戶不存在
  21. * 對輸入的密碼和數(shù)據(jù)庫密碼進行比對,如果一致則認證通過
  22. */
  23. // 根據(jù)用戶賬號查詢數(shù)據(jù)庫
  24. SysUser sysUser = this.findSysUserByUserCode(usercode);
  25. if (sysUser == null) {
  26. // 拋出異常
  27. throw new CustomException("用戶賬號不存在");
  28. }
  29. // 數(shù)據(jù)庫密碼(MD5加密后的密碼)
  30. String password_db = sysUser.getPassword();
  31. // 對輸入的密碼和數(shù)據(jù)庫密碼進行比對,如果一致,認證通過
  32. // 對頁面輸入的密碼進行MD5加密
  33. String password_input_md5 = new MD5().getMD5ofStr(password);
  34. if (!password_db.equalsIgnoreCase(password_input_md5)) {
  35. //拋出異常
  36. throw new CustomException("用戶名或密碼錯誤");
  37. }
  38. //得到用戶id
  39. String userid = sysUser.getId();
  40. //根據(jù)用戶id查詢菜單
  41. List<SysPermission> menus = this.findMenuListByUserId(userid);
  42. //根據(jù)用戶id查詢權(quán)限url
  43. List<SysPermission> permissions = this.findPermissionListByUserId(userid);
  44. //認證通過,返回用戶身份信息
  45. ActiveUser activeUser = new ActiveUser();
  46. activeUser.setUserid(userid);
  47. activeUser.setUsercode(usercode);
  48. activeUser.setUsername(sysUser.getUsername());
  49. //放入權(quán)限范圍的菜單和url
  50. activeUser.setMenus(menus);
  51. activeUser.setPermissions(permissions);
  52. return activeUser;
  53. }
  54. public SysUser findSysUserByUserCode(String userCode) throws Exception {
  55. SysUserExample sysUserExample = new SysUserExample();
  56. SysUserExample.Criteria criteria = sysUserExample.createCriteria();
  57. criteria.andUsercodeEqualTo(userCode);
  58. List<SysUser> list = sysUserMapper.selectByExample(sysUserExample);
  59. if (list != null && list.size() > 0) {
  60. return list.get(0);
  61. }
  62. return null;
  63. }
  64. @Override
  65. public List<SysPermission> findMenuListByUserId(String userid) throws Exception {
  66. return sysPermissionMapperCustom.findMenuListByUserId(userid);
  67. }
  68. @Override
  69. public List<SysPermission> findPermissionListByUserId(String userid) throws Exception {
  70. return sysPermissionMapperCustom.findPermissionListByUserId(userid);
  71. }
  72. }
登錄控制器
  1. package liuxun.ssm.controller;
  2. import javax.servlet.http.HttpSession;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import liuxun.ssm.exception.CustomException;
  7. import liuxun.ssm.po.ActiveUser;
  8. import liuxun.ssm.service.SysService;
  9. /**
  10. * 登錄和退出
  11. * @author liuxun
  12. *
  13. */
  14. @Controller
  15. public class LoginController {
  16. @Autowired
  17. private SysService sysService;
  18. //用戶登錄提交方法
  19. @RequestMapping("/login")
  20. public String login(HttpSession session,String randomcode,String usercode,String password) throws Exception{
  21. // 校驗驗證碼,防止惡性攻擊
  22. // 從Session中獲取正確的驗證碼
  23. String validateCode = (String) session.getAttribute("validateCode");
  24. //輸入的驗證碼和Session中的驗證碼進行對比
  25. if (!randomcode.equalsIgnoreCase(validateCode)) {
  26. //拋出異常
  27. throw new CustomException("驗證碼輸入錯誤");
  28. }
  29. //調(diào)用Service校驗用戶賬號和密碼的正確性
  30. ActiveUser activeUser = sysService.authenticat(usercode, password);
  31. //如果Service校驗通過,將用戶身份記錄到Session
  32. session.setAttribute("activeUser", activeUser);
  33. //重定向到商品查詢頁面
  34. return "redirect:/first.action";
  35. }
  36. //用戶退出
  37. @RequestMapping("/logout")
  38. public String logout(HttpSession session) throws Exception{
  39. //session失效
  40. session.invalidate();
  41. //重定向到商品查詢頁面
  42. return "redirect:/first.action";
  43. }
  44. }
身份認證攔截器LoginInterceptor.java
  1. package liuxun.ssm.controller.interceptor;
  2. import java.util.List;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import javax.servlet.http.HttpSession;
  6. import org.springframework.web.servlet.HandlerInterceptor;
  7. import org.springframework.web.servlet.ModelAndView;
  8. import liuxun.ssm.po.ActiveUser;
  9. import liuxun.ssm.util.ResourcesUtil;
  10. /**
  11. * 測試攔截器1
  12. * @author liuxun
  13. *
  14. */
  15. public class LoginInterceptor implements HandlerInterceptor{
  16. //在執(zhí)行handler之前執(zhí)行的
  17. //用于用戶認證校驗、用戶權(quán)限校驗
  18. @Override
  19. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  20. //得到請求的url
  21. String url = request.getRequestURI();
  22. //判斷是否是公開地址
  23. //實際開發(fā)中需要將公開地址配置在配置文件中
  24. //從配置文件中取出可以匿名訪問的URL
  25. List<String> open_urls = ResourcesUtil.getKeyList("anonymousURL");
  26. for (String open_url : open_urls) {
  27. if (url.indexOf(open_url)>=0) {
  28. //如果是公開地址 則放行
  29. return true;
  30. }
  31. }
  32. //判斷用戶身份在Session中是否存在
  33. HttpSession session = request.getSession();
  34. ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
  35. //如果用戶身份在session中存在則放行
  36. if (activeUser!=null) {
  37. return true;
  38. }
  39. //執(zhí)行到這里攔截,跳轉(zhuǎn)到登錄頁面,用戶進行身份認證
  40. request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
  41. //如果返回false表示攔截器不繼續(xù)執(zhí)行handler,如果返回true表示放行
  42. return false;
  43. }
  44. //在執(zhí)行handler返回modelAndView之前執(zhí)行
  45. //如果需要向頁面提供一些公用的數(shù)據(jù)或配置一些視圖信息,使用此方法實現(xiàn) 從modelAndView入手
  46. @Override
  47. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
  48. throws Exception {
  49. System.out.println("HandlerInterceptor2...postHandle");
  50. }
  51. //執(zhí)行handler之后執(zhí)行此方法
  52. //作為系統(tǒng)統(tǒng)一異常處理,進行方法執(zhí)行性能監(jiān)控,在preHandler中設置一個時間點 在afterCompletion設置一個時間點 二者時間差就是執(zhí)行時長
  53. //實現(xiàn)系統(tǒng),統(tǒng)一日志記錄
  54. @Override
  55. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception modelAndView)
  56. throws Exception {
  57. System.out.println("HandlerInterceptor2...afterCompletion");
  58. }
  59. }
資源授權(quán)攔截器PermissionInterceptor
  1. package liuxun.ssm.controller.interceptor;
  2. import java.security.acl.Permission;
  3. import java.util.List;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import javax.servlet.http.HttpSession;
  7. import org.springframework.web.servlet.HandlerInterceptor;
  8. import org.springframework.web.servlet.ModelAndView;
  9. import liuxun.ssm.po.ActiveUser;
  10. import liuxun.ssm.po.SysPermission;
  11. import liuxun.ssm.util.ResourcesUtil;
  12. /**
  13. * 授權(quán)攔截器
  14. * @author liuxun
  15. *
  16. */
  17. public class PermissionInterceptor implements HandlerInterceptor{
  18. //在執(zhí)行handler之前執(zhí)行的
  19. //用于用戶認證校驗、用戶權(quán)限校驗
  20. @Override
  21. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  22. //得到請求的url
  23. String url = request.getRequestURI();
  24. //判斷是否是公開地址
  25. //實際開發(fā)中需要將公開地址配置在配置文件中
  26. //從配置文件中取出可以匿名訪問的URL
  27. List<String> open_urls = ResourcesUtil.getKeyList("anonymousURL");
  28. for (String open_url : open_urls) {
  29. if (url.indexOf(open_url)>=0) {
  30. //如果是公開地址 則放行
  31. return true;
  32. }
  33. }
  34. //從配置文件中獲取公用訪問url
  35. List<String> common_urls = ResourcesUtil.getKeyList("commonURL");
  36. //遍歷公用地址 如果是公開地址則放行
  37. for (String common_url : common_urls) {
  38. if (url.indexOf(common_url)>0) {
  39. //如果是公開,則放行
  40. return true;
  41. }
  42. }
  43. //判斷用戶身份在Session中是否存在
  44. HttpSession session = request.getSession();
  45. ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
  46. //從Session中取出權(quán)限范圍的URL
  47. List<SysPermission> permissions = activeUser.getPermissions();
  48. for (SysPermission sysPermission : permissions) {
  49. //權(quán)限url
  50. String permission_url = sysPermission.getUrl();
  51. if (url.indexOf(permission_url)>0) {
  52. return true;
  53. }
  54. }
  55. //執(zhí)行到這里攔截,跳轉(zhuǎn)到無權(quán)訪問的提示頁面
  56. request.getRequestDispatcher("/WEB-INF/jsp/refuse.jsp").forward(request, response);
  57. //如果返回false表示攔截器不繼續(xù)執(zhí)行handler,如果返回true表示放行
  58. return false;
  59. }
  60. //在執(zhí)行handler返回modelAndView之前執(zhí)行
  61. //如果需要向頁面提供一些公用的數(shù)據(jù)或配置一些視圖信息,使用此方法實現(xiàn) 從modelAndView入手
  62. @Override
  63. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
  64. throws Exception {
  65. System.out.println("HandlerInterceptor2...postHandle");
  66. }
  67. //執(zhí)行handler之后執(zhí)行此方法
  68. //作為系統(tǒng)統(tǒng)一異常處理,進行方法執(zhí)行性能監(jiān)控,在preHandler中設置一個時間點 在afterCompletion設置一個時間點 二者時間差就是執(zhí)行時長
  69. //實現(xiàn)系統(tǒng),統(tǒng)一日志記錄
  70. @Override
  71. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception modelAndView)
  72. throws Exception {
  73. System.out.println("HandlerInterceptor2...afterCompletion");
  74. }
  75. }
攔截器配置
  1. <!-- 攔截器 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <!-- 用戶認證攔截 -->
  5. <mvc:mapping path="/**"/>
  6. <bean class="liuxun.ssm.controller.interceptor.LoginInterceptor"></bean>
  7. </mvc:interceptor>
  8. <mvc:interceptor>
  9. <!-- 資源攔截 -->
  10. <mvc:mapping path="/**"/>
  11. <bean class="liuxun.ssm.controller.interceptor.PermissionInterceptor"></bean>
  12. </mvc:interceptor>
  13. </mvc:interceptors>
使用URL攔截總結(jié):
使用基于URL攔截的權(quán)限管理方式,實現(xiàn)起來比較簡單,不依賴框架使用過濾器或攔截器就可以實現(xiàn) 
弊端:需要將所有的URL全部配置起來,比較繁瑣,不易維護,URL(資源)和權(quán)限表示方式不規(guī)范

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多