天天看點

springboot內建shiro的實體

3.身份認證

在認證、授權内部實作機制中都有提到,最終處理都将交給Real進行處理。因為在Shiro中,最終是通過Realm來擷取應用程式中的使用者、角色及權限資訊的。通常情況下,在Realm中會直接從我們的資料源中擷取Shiro需要的驗證資訊。可以說,Realm是專用于安全架構的DAO.

認證實作

Shiro

的認證過程最終會交由

Realm

執行,這時會調用

Realm

getAuthenticationInfo(token)

方法。

該方法主要執行以下操作:

1、檢查送出的進行認證的令牌資訊

2、根據令牌資訊從資料源(通常為資料庫)中擷取使用者資訊

3、對使用者資訊進行比對驗證。

4、驗證通過将傳回一個封裝了使用者資訊的

AuthenticationInfo

執行個體。

5、驗證失敗則抛出

AuthenticationException

異常資訊。

而在我們的應用程式中要做的就是自定義一個

Realm

類,繼承

AuthorizingRealm

抽象類,重載

doGetAuthenticationInfo ()

,重寫擷取使用者資訊的方法。

既然需要進行身份權限控制,那麼少不了建立使用者實體類,權限實體類。

在權限管理系統中,有這麼幾個角色很重要,這個要是不清楚的話,那麼就很難了解,我們為什麼這麼編碼了。

第一是

使用者表

:在使用者表中儲存了使用者的基本資訊,賬号、密碼、姓名,性别等;

第二是:

權限表(資源+控制權限)

:這個表中主要是儲存了使用者的URL位址,權限資訊;

第三就是

角色表

:在這個表重要儲存了系統存在的角色;

第四就是

關聯表

:使用者-角色管理表(使用者在系統中都有什麼角色,比如admin,vip等),

第五就是

角色-權限關聯表

(每個角色都有什麼權限可以進行操作)。依據這個理論,我們進行來進行編碼,很明顯的我們第一步就是要進行實體類的建立。在這裡我們使用Mysql和JPA進行操作資料庫。

引入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驅動; -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
           

application.yml配置mysql資料庫和JPA

spring:
    datasource:
      url: jdbc:mysql://localhost:3306/資料庫名稱
      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

至于之前的關聯表我們使用JPA進行自動生成。

UserInfo使用者資訊實體類

@Entity

聲明為實體類

@Id``@GeneratedValue

說Id是個自增主鍵,映射到你這個類中的Integer uid

@Column(unique =true)

是指username這個字段的值在這張表裡不能重複,所有記錄值都要唯一,就像主鍵那樣

@ManyToMany(fetch=FetchType.EAGER)

不寫預設為

LAZY

如果是

EAGER

,那麼表示取出這條資料時,它關聯的資料也同時取出放入記憶體中.

LAZY

,那麼取出這條資料時,它關聯的資料并不取出來

表關聯

@JoinTable

name

屬性為連接配接兩個表的表名稱。若不指定,則使用預設的表名稱,格式:

"表名1" + "_" + "表名2"

(JPA會為我們建立這個表)

joinColumn

屬性表示,在儲存關系的表中,所儲存關聯關系的外鍵的字段,并配合

@JoinColumn

标記使用;

inverseJoinColumn

屬性與

joinColumn

類似,它儲存的是儲存關系的另外一個外鍵字段;

@Entity
public class UserInfo implements Serializable{
    @Id@GeneratedValue
    private Integer uid;
    @Column(unique =true)
    private String username;//帳号
    private String name;//名稱(昵稱或者真實姓名,不同系統不同定義)
    private String password; //密碼;
    private String salt;//加密密碼的鹽
    private byte state;//使用者狀态,0:建立未認證(比如沒有激活,沒有輸入驗證碼等等)--等待驗證的使用者 , 1:正常狀态,2:使用者被鎖定.
    @ManyToMany(fetch=FetchType.EAGER)//立即從資料庫中進行加載資料;
    @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

系統角色實體類

@Entity
public class SysRole {
    @Id@GeneratedValue
    private Integer id; // 編号
    private String role; // 角色辨別程式中判斷使用,如"admin",這個是唯一的:
    private String description; // 角色描述,UI界面顯示使用
    private Boolean available = Boolean.FALSE; // 是否可用,如果不可用将不會添加給使用者

    //角色 -- 權限關系:多對多關系;
    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})
    private List<SysPermission> permissions;

    // 使用者 - 角色關系定義;
    @ManyToMany
    @JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="uid")})
    private List<UserInfo> userInfos;// 一個角色對應多個使用者
    set和get方法....
}
           

SysPermission

權限實體類

@Column(columnDefinition="enum('menu','button')")``columnDefinition

屬性表示建立表時,該字段建立的SQL語句,一般用于通過Entity生成表定義時使用。

例如

columnDefinition

屬性的特殊使用:

程式設計語言中字元串一般都用

String

表示,但是資料庫中

varcahr

數值類型有長度限制,一旦需要大文本,則需要

text

數值類型

但是String類型預設映射的數值類型是

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; //權限字元串,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

對應的是資料庫的五張表:

UserInfo

SysUserRole

SysRole

SysRolePermission

SysPermission

(隻需要跑一下程式就會開始建立表)

建立完表之後要輸入下資料

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');
           

下一篇文章将講實作身份認證,權限控制

文章主要參考于作者林祥纖的部落格

http://412887952-qq-com.iteye.com/blog/2299777