環(huán)境搭建
數(shù)據(jù)庫
使用mysql數(shù)據(jù)庫,并創(chuàng)建用戶表,角色表,權(quán)限表,用戶角色表,角色權(quán)限表
/*
SQLyog v10.2
MySQL - 5.1.72-community : Database - shiro
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
/*Table structure for table `sys_permission` */
CREATE TABLE `sys_permission` (
`id` bigint(20) NOT NULL COMMENT '主鍵',
`name` varchar(128) NOT NULL COMMENT '資源名稱',
`type` varchar(32) NOT NULL COMMENT '資源類型:menu,button,',
`url` varchar(128) DEFAULT NULL COMMENT '訪問url地址',
`percode` varchar(128) DEFAULT NULL COMMENT '權(quán)限代碼字符串',
`parentid` bigint(20) DEFAULT NULL COMMENT '父結(jié)點id',
`parentids` varchar(128) DEFAULT NULL COMMENT '父結(jié)點id列表串',
`sortstring` varchar(128) DEFAULT NULL COMMENT '排序號',
`available` char(1) DEFAULT NULL COMMENT '是否可用,1:可用,0不可用',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Table structure for table `sys_role` */
CREATE TABLE `sys_role` (
`id` varchar(36) NOT NULL,
`name` varchar(128) NOT NULL,
`available` char(1) DEFAULT NULL COMMENT '是否可用,1:可用,0不可用',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Table structure for table `sys_role_permission` */
CREATE TABLE `sys_role_permission` (
`id` varchar(36) NOT NULL,
`sys_role_id` varchar(32) NOT NULL COMMENT '角色id',
`sys_permission_id` varchar(32) NOT NULL COMMENT '權(quán)限id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Table structure for table `sys_user` */
CREATE TABLE `sys_user` (
`id` varchar(36) NOT NULL COMMENT '主鍵',
`usercode` varchar(32) NOT NULL COMMENT '賬號',
`username` varchar(64) NOT NULL COMMENT '姓名',
`password` varchar(32) NOT NULL COMMENT '密碼',
`salt` varchar(64) DEFAULT NULL COMMENT '鹽',
`locked` char(1) DEFAULT NULL COMMENT '賬號是否鎖定,1:鎖定,0未鎖定',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Table structure for table `sys_user_role` */
CREATE TABLE `sys_user_role` (
`id` varchar(36) NOT NULL,
`sys_user_id` varchar(32) NOT NULL,
`sys_role_id` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
/*
SQLyog v10.2
MySQL - 5.1.72-community : Database - shiro
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
/*Data for the table `sys_permission` */
insert into `sys_permission`(`id`,`name`,`type`,`url`,`percode`,`parentid`,`parentids`,`sortstring`,`available`) values (1,'權(quán)限','','',NULL,0,'0/','0','1'),(11,'商品管理','menu','/item/queryItem.action',NULL,1,'0/1/','1.','1'),(12,'商品新增','permission','/item/add.action','item:create',11,'0/1/11/','','1'),(13,'商品修改','permission','/item/editItem.action','item:update',11,'0/1/11/','','1'),(14,'商品刪除','permission','','item:delete',11,'0/1/11/','','1'),(15,'商品查詢','permission','/item/queryItem.action','item:query',11,'0/1/15/',NULL,'1'),(21,'用戶管理','menu','/user/query.action','user:query',1,'0/1/','2.','1'),(22,'用戶新增','permission','','user:create',21,'0/1/21/','','1'),(23,'用戶修改','permission','','user:update',21,'0/1/21/','','1'),(24,'用戶刪除','permission','','user:delete',21,'0/1/21/','','1');
/*Data for the table `sys_role` */
insert into `sys_role`(`id`,`name`,`available`) values ('ebc8a441-c6f9-11e4-b137-0adc305c3f28','商品管理員','1'),('ebc9d647-c6f9-11e4-b137-0adc305c3f28','用戶管理員','1');
/*Data for the table `sys_role_permission` */
insert into `sys_role_permission`(`id`,`sys_role_id`,`sys_permission_id`) values ('ebc8a441-c6f9-11e4-b137-0adc305c3f21','ebc8a441-c6f9-11e4-b137-0adc305c','12'),('ebc8a441-c6f9-11e4-b137-0adc305c3f22','ebc8a441-c6f9-11e4-b137-0adc305c','11'),('ebc8a441-c6f9-11e4-b137-0adc305c3f24','ebc9d647-c6f9-11e4-b137-0adc305c','21'),('ebc8a441-c6f9-11e4-b137-0adc305c3f25','ebc8a441-c6f9-11e4-b137-0adc305c','15'),('ebc9d647-c6f9-11e4-b137-0adc305c3f23','ebc9d647-c6f9-11e4-b137-0adc305c','22'),('ebc9d647-c6f9-11e4-b137-0adc305c3f26','ebc8a441-c6f9-11e4-b137-0adc305c','13');
/*Data for the table `sys_user` */
insert into `sys_user`(`id`,`usercode`,`username`,`password`,`salt`,`locked`) values ('lisi','lisi','李四','bf07fd8bbc73b6f70b8319f2ebb87483','uiwueylm','0'),('zhangsan','zhangsan','張三','cb571f7bd7a6f73ab004a70322b963d5','eteokues','0');
/*Data for the table `sys_user_role` */
insert into `sys_user_role`(`id`,`sys_user_id`,`sys_role_id`) values ('ebc8a441-c6f9-11e4-b137-0adc305c3f28','zhangsan','ebc8a441-c6f9-11e4-b137-0adc305c'),('ebc9d647-c6f9-11e4-b137-0adc305c3f28','lisi','ebc9d647-c6f9-11e4-b137-0adc305c');
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
sys_user表: 用戶表
sys_role表: 角色表
sys_permission表: 權(quán)限表
sys_user_role表: 用戶和角色的關(guān)系
sys_role_permission表: 角色和權(quán)限的關(guān)系
java環(huán)境
使用springMVC+Mybatis,必須要運行起來.
基于URL權(quán)限管理流程
實現(xiàn)思路是:將系統(tǒng)操作的每個url配置在權(quán)限表中,將權(quán)限對應(yīng)到角色,將角色分配給用戶,用戶訪問系統(tǒng)功能通過Filter進行過慮,過慮器獲取到用戶訪問的url,只要訪問的url是用戶分配角色中的url則放行繼續(xù)訪問。
基于URL權(quán)限管理流程
根據(jù)上面的流程圖,我們也可以看出來重點是在URL公開地址這一塊,接下來我們詳細(xì)說一說.
用戶認(rèn)證攔截器
anonymousURL.properties
anonymousURL.properties文件就是我們的公開地址文件, 也就是匿名的配置文件.
我們在我們的文件中配置一條如下消息
login.action = 用戶登錄
這樣大家就知道這個文件是干什么的了吧?在這個文件中配置的東西我們不需要登錄就能訪問.
文件配置完成后,我們就需要使用攔截器進行操作,思路是,例如我們要訪問login.action的時候由于在我們的匿名文件中可以找到,所以攔截器可以放行.
再例如當(dāng)我們訪問orderQuery.action的時候,這個url是不在匿名配置文件中的,所以攔截器就會判斷是否登錄了,如果沒有登錄就跳轉(zhuǎn)到登陸頁面,如果登錄就會繼續(xù)往下執(zhí)行.
編寫認(rèn)證攔截器
首先我給大家一個類用來讀取我們的匿名配置文件
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
/**
* 資源文件讀取工具類
*
*/
public class ResourcesUtil implements Serializable {
private static final long serialVersionUID = -7657898714983901418L;
/**
* 系統(tǒng)語言環(huán)境,默認(rèn)為中文zh
*/
public static final String LANGUAGE = "zh";
/**
* 系統(tǒng)國家環(huán)境,默認(rèn)為中國CN
*/
public static final String COUNTRY = "CN";
private static Locale getLocale() {
Locale locale = new Locale(LANGUAGE, COUNTRY);
return locale;
}
/**
* 根據(jù)語言、國家、資源文件名和key名字獲取資源文件值
*
* @param language
* 語言
*
* @param country
* 國家
*
* @param baseName
* 資源文件名
*
* @param section
* key名字
*
* @return 值
*/
private static String getProperties(String baseName, String section) {
String retValue = "";
try {
Locale locale = getLocale();
ResourceBundle rb = ResourceBundle.getBundle(baseName, locale);
retValue = (String) rb.getObject(section);
} catch (Exception e) {
e.printStackTrace();
// TODO 添加處理
}
return retValue;
}
/**
* 通過key從資源文件讀取內(nèi)容
*
* @param fileName
* 資源文件名
*
* @param key
* 索引
*
* @return 索引對應(yīng)的內(nèi)容
*/
public static String getValue(String fileName, String key) {
String value = getProperties(fileName,key);
return value;
}
public static List<String> getkeyList(String baseName) {
Locale locale = getLocale();
ResourceBundle rb = ResourceBundle.getBundle(baseName, locale);
List<String> reslist = new ArrayList<String>();
Set<String> keyset = rb.keySet();
for (Iterator<String> it = keyset.iterator(); it.hasNext();) {
String lkey = (String)it.next();
reslist.add(lkey);
}
return reslist;
}
/**
* 通過key從資源文件讀取內(nèi)容,并格式化
*
* @param fileName
* 資源文件名
*
* @param key
* 索引
*
* @param objs
* 格式化參數(shù)
*
* @return 格式化后的內(nèi)容
*/
public static String getValue(String fileName, String key, Object[] objs) {
String pattern = getValue(fileName, key);
String value = MessageFormat.format(pattern, objs);
return value;
}
public static void main(String[] args) {
System.out.println(getValue("resources.messages", "101",new Object[]{100,200}));
//根據(jù)操作系統(tǒng)環(huán)境獲取語言環(huán)境
/*Locale locale = Locale.getDefault();
System.out.println(locale.getCountry());//輸出國家代碼
System.out.println(locale.getLanguage());//輸出語言代碼s
//加載國際化資源(classpath下resources目錄下的messages.properties,如果是中文環(huán)境會優(yōu)先找messages_zh_CN.properties)
ResourceBundle rb = ResourceBundle.getBundle("resources.messages", locale);
String retValue = rb.getString("101");//101是messages.properties文件中的key
System.out.println(retValue);
//信息格式化,如果資源中有{}的參數(shù)則需要使用MessageFormat格式化,Object[]為傳遞的參數(shù),數(shù)量根據(jù)資源文件中的{}個數(shù)決定
String value = MessageFormat.format(retValue, new Object[]{100,200});
System.out.println(value);
*/
}
}
最終代碼
最終代碼