1. 程式人生 > >shiro框架java使用

shiro框架java使用

大綱

Shiro簡介及架構圖講解

ini配置檔案講解

Shiro搭建及簡單認證實現

加密及憑證匹配器

Spring整合Shiro完成登入功能.

 

知識點詳解

一、Shiro簡介

1.Shiro一個Java許可權框架.

1.1在專案中把涉及到許可權的業務提出來用shiro完成.

2.Shiro架構圖

2.1 Subject 主體.對應一個使用者,使用者所有的資訊都存放在Subject中.無論什麼程式語言只要有Subject都可以使用Shiro框架.

2.2 Cryptography: Shiro密碼管理功能.

2.2.1 密碼加密,加鹽,迭代等等.

2.3 Security Manager: 許可權管理器.Shiro核心內容.所有Shiro功能都封裝到Security Manager

2.4 Authenticator: 認證器. 例如登入註冊等功能就屬性認證功能.

2.5 Authorizer:授權器. 例如:判斷使用者是否具有某個角色,判斷使用者是否有某個許可權,判斷使用者可以訪問的選單.

2.6 Session Manager : Session管理器.使用Shiro後,shiro會禁用HttpSession,使用Shiiro自己的Session管理器.

2.7 Cache Manager : 快取管理. 支援Cookie的快取(remember me),支援Redis的快取.

2.8 Realm: 域.作用是當Shiro希望訪問資料庫時,通過Realm元件完成的.

 

二、Shiro.ini檔案

1.ini (InitializationFile) 初始檔案.Window系統副檔名.

2.Shiro 使用時可以連線資料庫,也可以不連線資料庫.

2.1 如果不連線資料庫,可以在shiro.ini中配置靜態資料.

3. Shiro.ini檔案組成部分

3.1[main] :定義全域性變數

3.1.1 內建securityManager物件.

3.1.2 操作內建物件時,在[main]裡面寫東西\

[main]

securityManager.屬性=值

 

myobj=com.bjsxt.lei

securityManager.物件屬性=$myobj

3.2[users] :定義使用者名稱和密碼

[users]

# 定義使用者名稱為zhangsan 密碼為zs

zhangsan=zs

# 定義使用者名稱lisi密碼為lisi同時具有role1和role2兩個角色

lisi=lisi,role1,role2

3.3[roles]: 定義角色

[roles]

role1=許可權名1,許可權名2

role2=許可權3,許可權4

3.4[urls] : 定義哪些內建urls生效.在web應用時使用.

[urls]

url地址=內建filter或自定義filter

# 訪問時出現/login的url必須去認證.支援authc對應的Filter

/login=authc

# 任意的url都不需要進行認證等功能.

/** = anon

# 所有的內容都必須保證使用者已經登入.

/**=user

# url abc 訪問時必須保證使用者具有role1和role2角色.

/abc=roles[“role1,role2”]

三、Shiro 環境搭建實現認證

認證流程

 

實現步驟

2.1 在pom.xml中匯入jar

   <dependencies>

      <dependency>

         <groupId>org.apache.shiro</groupId>

         <artifactId>shiro-core</artifactId>

         <version>1.3.2</version>

      </dependency>

      <!-- <dependency>

         <groupId>commons-logging</groupId>

         <artifactId>commons-logging</artifactId>

         <version>1.2</version>

      </dependency> -->

   </dependencies>

2.2 在src /java/resources下新建shiro.ini檔案

[users]

zhangsan=zs

2.3 編寫程式碼,實現認證

      // SecurityManager JDK也有這個類,在java.lang包

      Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

      SecurityManager sm = factory.getInstance();

      // 只要執行緒不變,Subject不變

      SecurityUtils.setSecurityManager(sm);

      Subject subject = SecurityUtils.getSubject();

      // Subject subject = (new Subject.Builder()).buildSubject();

      // 客戶端傳遞過來的使用者名稱和密碼

      UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "zs");

      try {

         subject.login(token);

         System.out.println("登入成功");

      } catch (UnknownAccountException e) {

         System.out.println("賬戶不存在");

      } catch (IncorrectCredentialsException e) {

         System.out.println("密碼錯誤");

      }

四、實現授權

1.流程圖

2.常用api

2.1 subject.hasRole(“”); 判斷是否有角色

2.2 subject.hashRoles(List);分別判斷使用者是否具有List中每個內容

2.3 subject.hasAllRoles(Collection);返回boolean,要求引數中所有角色使用者都需要具有.

2.4 subject.isPermitted(“”);判斷是否具有許可權.

五、自定義Realm

1. Principal:身份

1.1 使用者名稱可以是身份

1.2 郵箱可以是身份.

1.3 手機可以是身份.

1.4 使用者物件也可以是身份.

2.Credentials:憑證.

2.1 密碼可以是憑證

2.2 證書也是可以是憑證.

3. SecurityManager介面只有一個普通javaDefaultSecurityManager

4. 實現步驟:

4.1 新建類繼承AuthorizingRealm

4.2 doGetAuthenticationInfo實現認證過程.

4.3 程式碼

public class MyRealm extends AuthorizingRealm{

 

   //執行授權方法

   @Override

   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

      // TODO Auto-generated method stub

      return null;

   }

   //執行認證

   //當subject.login()時自動呼叫該方法

   @Override

   protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

      Object obj = token.getPrincipal();

      System.out.println("principal:"+obj);

      Object obj2 = token.getCredentials();

      new String((char[])obj2);

      System.out.println("credentials:"+new String((char[])obj2));

     

      //如果方法返回值為null,shiro認為使用者名稱不存在.

      //如果返回值不是null,判斷AuthenticationInfo中憑證和subject.login時憑證是否匹配

      //第一個引數: 第一個引數寫什麼以後登入這個使用者的身份就是什麼.

      //第二個引數是從資料庫中取出的憑證資訊,判斷這個資訊和subject.login()第二個引數是否匹配.

      //第三個引數:都是使用者主鍵值.

      SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(obj, "zs", "myrealm");

      return info;

   }

 

}

4.4 shiro.ini中配置自定義Realm

[main]

myrealm=com.bjsxt.realm.MyRealm

 

securityManager.realms=$myrealm

4.5 執行subject.login()呼叫doGetAuthenticationInfo

六. 憑證匹配器

1. 保證資料庫中密碼是加密的密碼

2.在shiro.ini中配置憑證匹配器

[main]

myrealm=com.bjsxt.realm.MyRealm

# 定義憑證匹配器類

credentialsMatcher =org.apache.shiro.authc.credential.HashedCredentialsMatcher

# 設定加密演算法

credentialsMatcher.hashAlgorithmName=md5

# 迭代次數

credentialsMatcher.hashIterations=2

# 引用憑證匹配器

myrealm.credentialsMatcher=$credentialsMatcher

 

securityManager.realms=$myrealm

3.在自定義realm中

3.1 第三個引數:加鹽值. 型別是ByteSource型別,bytes()跟字串型別,不能使用Long

SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(),rs.getObject("password"),

               ByteSource.Util.bytes(rs.getObject("id").toString())   ,"key:"+rs.getObject("id"));

七、自定義Realm中-doGetAuthorizationInfo()

   1.該方法被執行情況

  1. java中hasRole() , isPermitted();
  2. 使用註解

   @RequiresRoles("role1")

   @RequiresPermissions("")

    2.在jsp中標籤

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

 

   <shiro:hasRole name="role1">

      abc

   </shiro:hasRole>

   <shiro:hasPermission name="quanxian">

      jqk

   </shiro:hasPermission>