1. 程式人生 > >Shiro安全框架簡介以及身份驗證

Shiro安全框架簡介以及身份驗證

退出 ica 報錯 資源 帳戶 rac localhost file 手機號

一、Shiro簡介

官網 http://shiro.apache.org/download.html

Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼學和會話管理。使用Shiro的易於理解的API,您可以快速、輕松地獲得任何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序。

三個核心組件:Subject, SecurityManager 和 Realms. Subject:即“當前操作用戶”。但是,在Shiro中,Subject這一概念並不僅僅指人,也可以是第三方進程、後臺帳戶(Daemon Account)或其他類似事物。它僅僅意味著“當前跟軟件交互的東西”。但考慮到大多數目的和用途,你可以把它認為是Shiro的“用戶”概念。
  Subject代表了當前用戶的安全操作,SecurityManager則管理所有用戶的安全操作。
  SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通過SecurityManager來管理內部組件實例,並通過它來提供安全管理的各種服務。
  Realm: Realm充當了Shiro與應用安全數據間的“橋梁”或者“連接器”。也就是說,當對用戶執行認證(登錄)和授權(訪問控制)驗證時,Shiro會從應用配置的Realm中查找用戶及其權限信息。
  從這個意義上講,Realm實質上是一個安全相關的DAO:它封裝了數據源的連接細節,並在需要時將相關數據提供給Shiro。當配置Shiro時,你必須至少指定一個Realm,用於認證和(或)授權。配置多個Realm是可以的,但是至少需要一個。
  Shiro內置了可以連接大量安全數據源(又名目錄)的Realm,如LDAP、關系數據庫(JDBC)、類似INI的文本配置資源以及屬性文件等。如果缺省的Realm不能滿足需求,你還可以插入代表自定義數據源的自己的Realm實現。 ------來源百度百科 二、項目配置

1.創建一個Maven項目

2.下載shirojar包,因為是Maven管理的 所以添加下依賴,就從中央倉庫將jar包下載到本地倉庫了

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
    <dependency>
       <groupId>org.apache.shiro</groupId>
       <artifactId>shiro-core</artifactId>
       <
version>1.2.4</version> </dependency> </dependencies>

技術分享圖片

這個我下的是1.2.4版本,最新版本1.4.0,不支持IniSecurityManagerFactory解析ini,顯示構造函數過時 如下圖

技術分享圖片

有個slf4j api 包,這個是一個api接口包,我們還要引入slf4j的實現包,否則會報警告

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
    <dependency>
       <
groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> <scope>test</scope> </dependency>

<scope>標簽要刪除 否則會報如下錯誤

技術分享圖片

3.在src/main/resources/目錄下新建個shiro配置文件File,shiro.ini

建好後會彈出個記事本,關閉,不用記事本打開,右鍵選中openwith選TextEditor

[users]  //用戶
Robin=123456  //用戶名=密碼
Tom=123

4.在src/main/resources/目錄下加個log4j.properties日誌文件

5.在src/main/java目錄下建個包com.guo.shiro,包下新建個類HelloWorld.java

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;

import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
public class HelloWorld {
    public static void main(String[] args) {
        // 讀取配置文件,初始化SecurityManager工廠
        Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro.ini");
        // 獲取securityManager實例
        SecurityManager securityManager=factory.getInstance();
        // 把securityManager實例綁定到SecurityUtils
        SecurityUtils.setSecurityManager(securityManager);
        // 得到當前執行的用戶
        Subject currentUser=SecurityUtils.getSubject();
        // 創建token令牌,用戶名/密碼
        UsernamePasswordToken token=new UsernamePasswordToken("Robin", "123456");
        try{
            // 身份認證
            currentUser.login(token);    
            System.out.println("身份認證成功!");
        }catch(AuthenticationException e){
            e.printStackTrace();
            System.out.println("身份認證失敗!");
        }
        // 退出
        currentUser.logout();
    }
    }

這個身份驗證獲取的用戶名和密碼 是配置文件shiro.ini中的,要獲取和驗證數據庫中的用戶名和密碼,往下看

三、身份認證

1、Subject 認證主體

Subject 認證主體包含兩個信息: Principals:身份,可以是用戶名,郵件,手機號碼等,用來標識一個登錄主體身份; Credentials:憑證,常見有密碼,數字證書等等;

2、身份認證流程

技術分享圖片

Subject認證主體調用login()方法,傳給SecurityManager處理,SecurityManager裏有個

Authenticator實例,有個AuthenticatoStrategy策略,要讀取安全數據的話

涉及到Realm 來獲取安全數據

3、Realm

Realm:意思是域,Shiro 從 Realm 中獲取驗證數據; Realm 有很多種類,例如常見的 jdbcrealm,jndirealm,text realm。

4.以JDBCReaml 為例

a、 新建個db_shiro 庫,建個users表,添加用戶名Robin,密碼123456

技術分享圖片

b、在mvnrepori 查找C3P0 依賴代碼 和commons-logging 阿帕奇的公共日誌 依賴代碼

還有mysql的驅動包 依賴代碼 貼入pom

<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
     <dependency>
       <groupId>c3p0</groupId>
       <artifactId>c3p0</artifactId>
       <version>0.9.1.2</version>
     </dependency>
     
     <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <version>1.2</version>
    </dependency>
    
   <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
   <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.38</version>
   </dependency>

c、新建個jdbc_reaml.ini配置JDBCReaml

[main]
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://localhost:3306/db_shiro
dataSource.user=root
dataSource.password=123456
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm 

dataSource=com.mchange.v2.c3p0.ComboPooledDataSource 是下圖中的jar包

技術分享圖片

dataSource=com.mchange.v2.c3p0.ComboPooledDataSource

(相當於實例化一個ComboPooledDataSource的對象dataSource)

dataSource.driverClass=com.mysql.jdbc.Driver

(相當於對象dataSource調用ComboPooledDataSource類中的setdiverClass方法,將mysql驅動設置進去)

jdbcRealm.dataSource=$dataSource

(將dataSource=com.mchange.v2.c3p0.ComboPooledDataSource中的dataSource對象賦值給

jdbcRealm.dataSource,用$相當於將dataSource對象引用過去。jdbcRealm點後的這個dataSource是下圖中的setDataSource方法參數

技術分享圖片

jdbcRealm放入securityManager中,securityManager可以放多個屬性用逗號隔開。

d、下來package com.guo.shiro.HelloWorld.java中代碼

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;

import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
public class HelloWorld {
    public static void main(String[] args) {
        // 讀取配置文件,初始化SecurityManager工廠
        Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:jdbc_reaml.ini");
        // 獲取securityManager實例
        SecurityManager securityManager=factory.getInstance();
        // 把securityManager實例綁定到SecurityUtils
        SecurityUtils.setSecurityManager(securityManager);
        // 得到當前執行的用戶
        Subject currentUser=SecurityUtils.getSubject();
        // 創建token令牌,用戶名/密碼
        UsernamePasswordToken token=new UsernamePasswordToken("Robin", "123456");
        try{
            // 身份認證
            currentUser.login(token);    
            System.out.println("身份認證成功!");
        }catch(AuthenticationException e){
            e.printStackTrace();
            System.out.println("身份認證失敗!");
        }
        // 退出
        currentUser.logout();
    }
    }

5、錯誤

建表名為users ,不能建為t_user會報錯

Shiro安全框架簡介以及身份驗證