3.身份認證
在認證、授權(quán)內(nèi)部實現(xiàn)機制中都有提到炉擅,最終處理都將交給Real進行處理破衔。因為在Shiro中清女,最終是通過Realm來獲取應(yīng)用程序中的用戶、角色及權(quán)限信息的晰筛。通常情況下校仑,在Realm中會直接從我們的數(shù)據(jù)源中獲取Shiro需要的驗證信息〈荩可以說迄沫,Realm是專用于安全框架的DAO.
認證實現(xiàn)
Shiro
的認證過程最終會交由Realm
執(zhí)行,這時會調(diào)用Realm
的getAuthenticationInfo(token)
方法卦方。
該方法主要執(zhí)行以下操作:
1羊瘩、檢查提交的進行認證的令牌信息
2、根據(jù)令牌信息從數(shù)據(jù)源(通常為數(shù)據(jù)庫)中獲取用戶信息
3、對用戶信息進行匹配驗證尘吗。
4逝她、驗證通過將返回一個封裝了用戶信息的AuthenticationInfo
實例。
5睬捶、驗證失敗則拋出AuthenticationException
異常信息黔宛。
而在我們的應(yīng)用程序中要做的就是自定義一個Realm
類,繼承AuthorizingRealm
抽象類擒贸,重載doGetAuthenticationInfo ()
臀晃,重寫獲取用戶信息的方法。
既然需要進行身份權(quán)限控制介劫,那么少不了創(chuàng)建用戶實體類徽惋,權(quán)限實體類。
在權(quán)限管理系統(tǒng)中座韵,有這么幾個角色很重要险绘,這個要是不清楚的話,那么就很難理解誉碴,我們?yōu)槭裁催@么編碼了宦棺。
第一是用戶表
:在用戶表中保存了用戶的基本信息,賬號黔帕、密碼代咸、姓名,性別等蹬屹;
第二是:權(quán)限表(資源+控制權(quán)限)
:這個表中主要是保存了用戶的URL地址侣背,權(quán)限信息;
第三就是角色表
:在這個表重要保存了系統(tǒng)存在的角色慨默;
第四就是關(guān)聯(lián)表
:用戶-角色管理表(用戶在系統(tǒng)中都有什么角色贩耐,比如admin,vip等)厦取,
第五就是角色-權(quán)限關(guān)聯(lián)表
(每個角色都有什么權(quán)限可以進行操作)潮太。依據(jù)這個理論,我們進行來進行編碼虾攻,很明顯的我們第一步就是要進行實體類的創(chuàng)建铡买。在這里我們使用Mysql和JPA進行操作數(shù)據(jù)庫。
引入mysql和JPA的依賴霎箍。JPA版本(Mar 03, 2017)奇钞,mysql版本默認,可以自己選擇版本
<!-- Spirng data JPA依賴; -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>1.5.2.RELEASE</version>
</dependency>
<!-- mysql驅(qū)動; -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
application.yml配置mysql數(shù)據(jù)庫和JPA
spring:
datasource:
url: jdbc:mysql://localhost:3306/數(shù)據(jù)庫名稱
username: mysql的登錄帳號
password: mysql的登錄密碼
driver-class-name: com.mysql.jdbc.Driver
jpa:
database: mysql
show-sql: true
hibernate:
ddl-auto: update
naming:
strategy: org.hibernate.cfg.DefaultComponentSafeNamingStrategy
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
JPA強大之處在于可以自動建表,只要在實體類中用好注解
UserInfo
漂坏、SysRole
景埃、SysPermission
至于之前的關(guān)聯(lián)表我們使用JPA進行自動生成媒至。
UserInfo用戶信息實體類
@Entity
聲明為實體類
@Id``@GeneratedValue
說Id是個自增主鍵,映射到你這個類中的Integer uid
@Column(unique =true)
是指username這個字段的值在這張表里不能重復,所有記錄值都要唯一谷徙,就像主鍵那樣
@ManyToMany(fetch=FetchType.EAGER)
不寫默認為LAZY
如果是EAGER
拒啰,那么表示取出這條數(shù)據(jù)時,它關(guān)聯(lián)的數(shù)據(jù)也同時取出放入內(nèi)存中.
如果是LAZY
完慧,那么取出這條數(shù)據(jù)時谋旦,它關(guān)聯(lián)的數(shù)據(jù)并不取出來
表關(guān)聯(lián)@JoinTable
name
屬性為連接兩個表的表名稱。若不指定屈尼,則使用默認的表名稱册着,格式:"表名1" + "_" + "表名2"
(JPA會為我們新建這個表)
joinColumn
屬性表示,在保存關(guān)系的表中鸿染,所保存關(guān)聯(lián)關(guān)系的外鍵的字段指蚜,并配合@JoinColumn
標記使用乞巧;
inverseJoinColumn
屬性與joinColumn
類似涨椒,它保存的是保存關(guān)系的另外一個外鍵字段;
@Entity
public class UserInfo implements Serializable{
@Id@GeneratedValue
private Integer uid;
@Column(unique =true)
private String username;//帳號
private String name;//名稱(昵稱或者真實姓名绽媒,不同系統(tǒng)不同定義)
private String password; //密碼;
private String salt;//加密密碼的鹽
private byte state;//用戶狀態(tài),0:創(chuàng)建未認證(比如沒有激活蚕冬,沒有輸入驗證碼等等)--等待驗證的用戶 , 1:正常狀態(tài),2:用戶被鎖定.
@ManyToMany(fetch=FetchType.EAGER)//立即從數(shù)據(jù)庫中進行加載數(shù)據(jù);
@JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns ={@JoinColumn(name = "roleId") })
private List<SysRole> roleList;// 一個用戶具有多個角色
set和get方法....
/**
* 密碼鹽.
* @return
*/
public String getCredentialsSalt(){
return this.username+this.salt;
}
//重新對鹽重新進行了定義,用戶名+salt是辕,這樣就更加不容易被破解
}
SysRole
系統(tǒng)角色實體類
@Entity
public class SysRole {
@Id@GeneratedValue
private Integer id; // 編號
private String role; // 角色標識程序中判斷使用,如"admin",這個是唯一的:
private String description; // 角色描述,UI界面顯示使用
private Boolean available = Boolean.FALSE; // 是否可用,如果不可用將不會添加給用戶
//角色 -- 權(quán)限關(guān)系:多對多關(guān)系;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})
private List<SysPermission> permissions;
// 用戶 - 角色關(guān)系定義;
@ManyToMany
@JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="uid")})
private List<UserInfo> userInfos;// 一個角色對應(yīng)多個用戶
set和get方法....
}
SysPermission
權(quán)限實體類
@Column(columnDefinition="enum('menu','button')")``columnDefinition
屬性表示創(chuàng)建表時囤热,該字段創(chuàng)建的SQL語句,一般用于通過Entity生成表定義時使用获三。
例如
columnDefinition
屬性的特殊使用:
編程語言中字符串一般都用String
表示旁蔼,但是數(shù)據(jù)庫中varcahr
數(shù)值類型有長度限制,一旦需要大文本疙教,則需要text
數(shù)值類型
但是String類型默認映射的數(shù)值類型是varchar
棺聊,columnDefinition
可以進行額外指定
@Column(name = "Remark",columnDefinition="text") private String remark;
這里枚舉類型enum,resourceType只能是menu或者button,其他都不行
@Column(columnDefinition="enum('menu','button')")
private String resourceType;
具體的SysPermission
實體類
@Entity
public class SysPermission implements Serializable{
@Id@GeneratedValue
private Integer id;//主鍵.
private String name;//名稱.
@Column(columnDefinition="enum('menu','button')")
private String resourceType;//資源類型贞谓,[menu|button]
private String url;//資源路徑.
private String permission; //權(quán)限字符串,menu例子:role:*限佩,button例子:role:create,role:update,role:delete,role:view
private Long parentId; //父編號
private String parentIds; //父編號列表
private Boolean available = Boolean.FALSE;
@ManyToMany
@JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")})
private List<SysRole> roles;
set和get方法....
}
到這里實體類就編碼完畢了,在這里我們看到的是3個實體類:UserInfo
,SysRole
,SysPermission
對應(yīng)的是數(shù)據(jù)庫的五張表:
表UserInfo
裸弦、
表SysUserRole
祟同、
表SysRole
、
表SysRolePermission
理疙、
表SysPermission
(只需要跑一下程序就會開始創(chuàng)建表)
創(chuàng)建完表之后要輸入下數(shù)據(jù)
INSERT INTO `sys_permission` VALUES ('1', '?', '用戶管理', '0', '0/', 'userInfo:view', 'menu', 'userInfo/userList');
INSERT INTO `sys_permission` VALUES ('2', '?', '用戶添加', '1', '0/1', 'userInfo:add', 'button', 'userInfo/userAdd');
INSERT INTO `sys_permission` VALUES ('3', '?', '用戶刪除', '1', '0/1', 'userInfo:del', 'button', 'userInfo/userDel');
INSERT INTO `sys_role` VALUES ('1', '?', '管理員', 'admin');
INSERT INTO `sys_role` VALUES ('2', '?', 'VIP會員', 'vip');
INSERT INTO `sys_role_permission` VALUES ('1', '1');
INSERT INTO `sys_role_permission` VALUES ('1', '2');
INSERT INTO `sys_role_permission` VALUES ('1', '3');
INSERT INTO `sys_user_role` VALUES ('1', '1');
INSERT INTO `user_info` VALUES ('1', 'admin', '管理員', 'd3c59d25033dbf980d29554025c23a75', '8d78869f470951332959580424d4bf4f', '0');
下一篇文章將講實現(xiàn)身份認證晕城,權(quán)限控制