黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專(zhuān)注Java教育14年 全國(guó)咨詢(xún)/投訴熱線:400-8080-105
動(dòng)力節(jié)點(diǎn)LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁(yè) hot資訊 Shiro原理解析

Shiro原理解析

更新時(shí)間:2022-02-08 11:04:26 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1453次

1.shiro原理圖如下:

框架解釋?zhuān)?/p>

subject:主體,可以是用戶(hù)也可以是程序,主體要訪問(wèn)系統(tǒng),系統(tǒng)需要對(duì)主體進(jìn)行認(rèn)證、授權(quán)。

securityManager:安全管理器,主體進(jìn)行認(rèn)證和授權(quán)都 是通過(guò)securityManager進(jìn)行。它包含下面的認(rèn)證器和授權(quán)器。

authenticator:認(rèn)證器,主體進(jìn)行認(rèn)證最終通過(guò)authenticator進(jìn)行的。

authorizer:授權(quán)器,主體進(jìn)行授權(quán)最終通過(guò)authorizer進(jìn)行的。

sessionManager:web應(yīng)用中一般是用web容器對(duì)session進(jìn)行管理,shiro也提供一套session管理的方式。可以實(shí)現(xiàn)單點(diǎn)登錄。

SessionDao: 通過(guò)SessionDao管理session數(shù)據(jù),針對(duì)個(gè)性化的session數(shù)據(jù)存儲(chǔ)需要使用sessionDao。

cache Manager:緩存管理器,主要對(duì)session和授權(quán)數(shù)據(jù)進(jìn)行緩存,比如將授權(quán)數(shù)據(jù)通過(guò)cacheManager進(jìn)行緩存管理,和ehcache整合對(duì)緩存數(shù)據(jù)進(jìn)行管理。

realm:域,領(lǐng)域,相當(dāng)于數(shù)據(jù)源,通過(guò)realm存取認(rèn)證、授權(quán)相關(guān)數(shù)據(jù)。(它的主要目的是與數(shù)據(jù)庫(kù)打交道,查詢(xún)數(shù)據(jù)庫(kù)中的認(rèn)證的信息(比如用戶(hù)名和密碼),查詢(xún)授權(quán)的信息(比如權(quán)限的code等,所以這里可以理解為調(diào)用數(shù)據(jù)庫(kù)查詢(xún)一系列的信息,一般情況下在項(xiàng)目中采用自定義的realm,因?yàn)椴煌臉I(yè)務(wù)需求不一樣))

注意:在realm中存儲(chǔ)授權(quán)和認(rèn)證的邏輯。

cryptography:密碼管理,提供了一套加密/解密的組件,方便開(kāi)發(fā)。比如提供常用的散列、加/解密等功能。

比如 md5散列算法。

2.shiro介紹

shiro是apache的一個(gè)開(kāi)源框架,是一個(gè)權(quán)限管理的框架,實(shí)現(xiàn) 用戶(hù)認(rèn)證、用戶(hù)授權(quán)。

spring中有spring security (原名Acegi),是一個(gè)權(quán)限框架,它和spring依賴(lài)過(guò)于緊密,沒(méi)有shiro使用簡(jiǎn)單。

shiro不依賴(lài)于spring,shiro不僅可以實(shí)現(xiàn) web應(yīng)用的權(quán)限管理,還可以實(shí)現(xiàn)c/s系統(tǒng),分布式系統(tǒng)權(quán)限管理,shiro屬于輕量框架,越來(lái)越多企業(yè)項(xiàng)目開(kāi)始使用shiro。

使用shiro實(shí)現(xiàn)系統(tǒng) 的權(quán)限管理,有效提高開(kāi)發(fā)效率,從而降低開(kāi)發(fā)成本。

3.認(rèn)證原理:

(1)通過(guò)ini配置文件創(chuàng)建securityManager

(2)調(diào)用subject.login方法主體提交認(rèn)證,提交的token

(3)securityManager進(jìn)行認(rèn)證,securityManager最終由ModularRealmAuthenticator進(jìn)行認(rèn)證。

(4)ModularRealmAuthenticator調(diào)用IniRealm(給realm傳入token) 去ini配置文件中查詢(xún)用戶(hù)信息

(5)IniRealm根據(jù)輸入的token(UsernamePasswordToken,即這里的token是用戶(hù)從頁(yè)面輸入的信息)從 shiro-first.ini查詢(xún)用戶(hù)信息(這里是測(cè)試階段,后面都是查詢(xún)的數(shù)據(jù)庫(kù),注入service,調(diào)用dao),根據(jù)賬號(hào)查詢(xún)用戶(hù)信息(賬號(hào)和密碼)

如果查詢(xún)到用戶(hù)信息,就給ModularRealmAuthenticator返回用戶(hù)信息(賬號(hào)和密碼)

如果查詢(xún)不到,就給ModularRealmAuthenticator返回null

(6)ModularRealmAuthenticator接收IniRealm返回Authentication認(rèn)證信息

如果返回的認(rèn)證信息是null,ModularRealmAuthenticator拋出異常(org.apache.shiro.authc.UnknownAccountException)

如果返回的認(rèn)證信息不是null(說(shuō)明inirealm找到了用戶(hù)),對(duì)IniRealm返回用戶(hù)密碼 (在ini文件中存在)和 token中的密碼 進(jìn)行對(duì)比,如果不一致拋出異常(org.apache.shiro.authc.IncorrectCredentialsException)

小結(jié):

ModularRealmAuthenticator作用進(jìn)行認(rèn)證,需要調(diào)用realm查詢(xún)用戶(hù)信息(在數(shù)據(jù)庫(kù)中存在用戶(hù)信息)

ModularRealmAuthenticator進(jìn)行密碼對(duì)比(認(rèn)證過(guò)程)。

realm:需要根據(jù)token中的身份信息去查詢(xún)數(shù)據(jù)庫(kù)(入門(mén)程序使用ini配置文件),如果查到用戶(hù)返回認(rèn)證信息,如果查詢(xún)不到返回null。

4.散列算法:

通常需要對(duì)密碼 進(jìn)行散列,常用的有md5、sha,

shiro的散列加密是這樣子的:

建議對(duì)md5進(jìn)行散列時(shí)加salt(鹽),進(jìn)行加密相當(dāng) 于對(duì)原始密碼+鹽進(jìn)行散列。

即md5+salt(這個(gè)鹽一般是隨機(jī)鹽,即開(kāi)發(fā)人員給定義隨機(jī)的字符串或者數(shù)字即可)+散列次數(shù)

這里的md5是原始的md5的加密了一次的密碼+隨機(jī)鹽,然后對(duì)這個(gè)新的密碼password=(md5+salt),進(jìn)行散列:如何進(jìn)行散列呢:就是多次md5加密md5(md5(md5(md5(password)))),這是4次散列,每次密碼的破解的難度都加大。

正常使用時(shí)散列方法:

在程序中對(duì)原始密碼+鹽進(jìn)行散列,將散列值存儲(chǔ)到數(shù)據(jù)庫(kù)中,并且還要將鹽也要存儲(chǔ)在數(shù)據(jù)庫(kù)中。

如果進(jìn)行密碼對(duì)比時(shí),使用相同 方法,將原始密碼+鹽進(jìn)行散列,進(jìn)行比對(duì)。

5.授權(quán)原理

原理:

(1)對(duì)subject進(jìn)行授權(quán),調(diào)用方法isPermitted("permission串")

(2)SecurityManager執(zhí)行授權(quán),通過(guò)ModularRealmAuthorizer執(zhí)行授權(quán)

(3)ModularRealmAuthorizer執(zhí)行realm(自定義的CustomRealm)從數(shù)據(jù)庫(kù)查詢(xún)權(quán)限數(shù)據(jù)

調(diào)用realm的授權(quán)方法:doGetAuthorizationInfo

(4)realm從數(shù)據(jù)庫(kù)查詢(xún)權(quán)限數(shù)據(jù),返回ModularRealmAuthorizer

(5)ModularRealmAuthorizer調(diào)用PermissionResolver進(jìn)行權(quán)限串比對(duì)

(6)如果比對(duì)后,isPermitted中"permission串"在realm查詢(xún)到權(quán)限數(shù)據(jù)中,說(shuō)明用戶(hù)訪問(wèn)permission串有權(quán)限,否則 沒(méi)有權(quán)限,拋出異常。

shiro的授權(quán)方式有三種:

(1)—— 編程式:通過(guò)寫(xiě)if/else 授權(quán)代碼塊完成:(這種比較少用,一般在項(xiàng)目中采用后兩種)

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有權(quán)限
} else {
//無(wú)權(quán)限
}

(2)—— 注解式:通過(guò)在執(zhí)行的Java方法上放置相應(yīng)的注解完成:

@RequiresRoles("admin")
public void hello() {
//有權(quán)限
}

(3)—— JSP/GSP 標(biāo)簽:在JSP/GSP 頁(yè)面通過(guò)相應(yīng)的標(biāo)簽完成:

在jsp頁(yè)面導(dǎo)入shiro的標(biāo)簽既可以使用shiro的標(biāo)簽來(lái)進(jìn)行權(quán)限的判斷:

Jsp頁(yè)面添加:

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

<shiro:principal property="username"/>  顯示用戶(hù)身份中的屬性值

<shiro:hasRole name="admin">

<!— 有權(quán)限—>

</shiro:hasRole>

6.shiro與項(xiàng)目的整合:

整合無(wú)非就是jar包和配置文件:

配置文件:在web.xml中配置filter:

在web系統(tǒng)中,shiro也通過(guò)filter進(jìn)行攔截。filter攔截后將操作權(quán)交給spring中配置的filterChain(過(guò)慮鏈兒)

shiro提供很多filter。 在web.xml中配置filter

與spring的整合交由spring的容器管理:security manager 、realm、filter都交由spring整合

下面可以看下具體realm自定義使用與application_shiro的內(nèi)容:

realm

package  cn.project.ssm.shiro; 
import  java.security.acl.Permission;
import  java.util.ArrayList;
import  java.util.List; 
import  org.apache.shiro.SecurityUtils;
import  org.apache.shiro.authc.AuthenticationException;
import  org.apache.shiro.authc.AuthenticationInfo;
import  org.apache.shiro.authc.AuthenticationToken;
import  org.apache.shiro.authc.SimpleAuthenticationInfo;
import  org.apache.shiro.authz.AuthorizationInfo;
import  org.apache.shiro.authz.SimpleAuthorizationInfo;
import  org.apache.shiro.realm.AuthorizingRealm;
import  org.apache.shiro.subject.PrincipalCollection;
import  org.apache.shiro.util.ByteSource;
import  org.springframework.beans.factory.annotation.Autowired;
import  com.sun.org.apache.bcel.internal.generic.ACONST_NULL; 
import  cn.project.ssm.pojo.ActiveUser;
import  cn.project.ssm.pojo.SysPermission;
import  cn.project.ssm.pojo.SysUser;
import  cn.project.ssm.service.LoginService; 
/**
  *
  * <p>
  * Title: CustomRealm
  * </p>
  * <p>
  * Description:自定義realm,實(shí)際開(kāi)發(fā)中一般都是自定義realm
  * </p>
  * <p>
  * Company: www.itcast.com
  * </p>
  *  
  * @date 2015-3-23下午4:54:47
  * @version 1.0
  */
public  class  CustomRealm  extends  AuthorizingRealm {
     @Autowired
     private  LoginService loginService; 
     // 設(shè)置realm的名稱(chēng)
     @Override
     public  void  setName(String name) {
         super .setName( "customRealm" );
     }
     //用于認(rèn)證
     @Override
     protected  AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)  throws  AuthenticationException {
         //第一步:從token中取出用戶(hù)名,這個(gè)用戶(hù)名是用戶(hù)在頁(yè)面輸入的信息,傳遞給token
         String userCode=(String) token.getCredentials();
         //根據(jù)用戶(hù)名查詢(xún)用戶(hù)信息
         SysUser sysUser= null ;
         sysUser=loginService.findByUserCode(userCode);
         if  (sysUser== null ) {
             return  null ;   
         }
         String password=sysUser.getPassword();
         //加鹽
         String salt=sysUser.getSalt();
         //將用戶(hù)身份信息寫(xiě)入activeUser
         ActiveUser activeUser= new  ActiveUser();
         activeUser.setUserid(sysUser.getId());
         activeUser.setUsercode(sysUser.getUsercode());
         activeUser.setUsername(sysUser.getUsername());
         //通過(guò)service取出菜單
         List<SysPermission> menus= loginService.findmenusByUserId(sysUser.getId());     
         activeUser.setMenus(menus);         
         //寫(xiě)到這里我們看到realm其實(shí)主要是從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)
         SimpleAuthenticationInfo simpleAuthenticationInfo= new  SimpleAuthenticationInfo(activeUser,password,ByteSource.Util.bytes(salt),  this .getName());         
         return  simpleAuthenticationInfo;
     }
     //用于授權(quán)
     @Override
     protected  AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
     //從princal中獲取主身份信息,將返回值轉(zhuǎn)為真實(shí)的身份信息,填充到上面認(rèn)證的身份中
         ActiveUser activeUser=(ActiveUser) principal.getPrimaryPrincipal();
     //從數(shù)據(jù)庫(kù)中獲取到權(quán)限數(shù)據(jù)
         List<SysPermission> permissionsList = loginService.findpermissionByUserId(activeUser.getUserid());
         List<String> permissions= new  ArrayList<>();
         for  (SysPermission sysPermission : permissionsList) {
             permissions.add(sysPermission.getPercode());
         }
         //將集合內(nèi)容填充認(rèn)證中
         SimpleAuthorizationInfo simpleAuthorizationInfo= new  SimpleAuthorizationInfo();
         simpleAuthorizationInfo.addStringPermissions(permissions);
         return  simpleAuthorizationInfo;
     }
     //清除緩存
         public  void  clearCached() {
             PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
             super .clearCache(principals);
         } 
}

配置文件:

<?xml version= "1.0"  encoding= "UTF-8" ?>
<beans xmlns= "http://www.springframework.org/schema/beans"
     xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"  xmlns:mvc= "http://www.springframework.org/schema/mvc"
     xmlns:context= "http://www.springframework.org/schema/context"
     xmlns:aop= "http://www.springframework.org/schema/aop"  xmlns:tx= "http://www.springframework.org/schema/tx"
     xsi:schemaLocation="http: //www.springframework.org/schema/beans
         http: //www.springframework.org/schema/beans/spring-beans-3.2.xsd
         http: //www.springframework.org/schema/mvc
         http: //www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
         http: //www.springframework.org/schema/context
         http: //www.springframework.org/schema/context/spring-context-3.2.xsd
         http: //www.springframework.org/schema/aop
         http: //www.springframework.org/schema/aop/spring-aop-3.2.xsd
         http: //www.springframework.org/schema/tx
         http: //www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<!-- web.xml中shiro的filter對(duì)應(yīng)的bean -->
<!-- Shiro 的Web過(guò)濾器 -->
     <bean id= "shiroFilter"  class = "org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
         <property name= "securityManager"  ref= "securityManager"  />
         <!-- loginUrl認(rèn)證提交地址,如果沒(méi)有認(rèn)證將會(huì)請(qǐng)求此地址進(jìn)行認(rèn)證,請(qǐng)求此地址將由formAuthenticationFilter進(jìn)行表單認(rèn)證 -->
         <property name= "loginUrl"  value= "/login.action"  />
         <!-- 認(rèn)證成功統(tǒng)一跳轉(zhuǎn)到first.action,建議不配置,shiro認(rèn)證成功自動(dòng)到上一個(gè)請(qǐng)求路徑 -->
         <!-- <property name= "successUrl"  value= "/first.action" /> -->
         <!-- 通過(guò)unauthorizedUrl指定沒(méi)有權(quán)限操作時(shí)跳轉(zhuǎn)頁(yè)面-->
         <property name= "unauthorizedUrl"  value= "/refuse.jsp"  />         
         <!-- 過(guò)慮器鏈定義,從上向下順序執(zhí)行,一般將/**放在最下邊 -->
         <property name= "filterChainDefinitions" >
             <value>  
             <!-- 對(duì)靜態(tài)資源設(shè)置訪問(wèn),不然都攔截了 -->
             /images/**=anon
             /js/**=anon
             /styles/**=anon             
             <!-- 請(qǐng)求logout.action地址,shiro清除session -->
             /logout.action=logout
                 <!-- /** = authc所有url都可以認(rèn)證通過(guò)才能訪問(wèn) --> 
                 /** = authc
             <!-- /** = anon所有url都可以匿名訪問(wèn) -->  
                 /** = anon             
             </value>
         </property>
     </bean> 
<!-- securityManager安全管理器 -->
<bean id= "securityManager"  class = "org.apache.shiro.web.mgt.DefaultWebSecurityManager" >
         <property name= "realm"  ref= "customRealm"  />  
             <!-- 注入緩存管理器 -->
         <property name= "cacheManager"  ref= "cacheManager" />
     </bean> 
<!-- realm -->
<bean id= "customRealm"  class = "cn.project.ssm.shiro.CustomRealm" >
     <!-- 將憑證匹配器設(shè)置到realm中,realm按照憑證匹配器的要求進(jìn)行散列 -->
     <property name= "credentialsMatcher"  ref= "credentialsMatcher" />
</bean> 
<!-- 散列加鹽憑證匹配器 -->
<bean id= "credentialsMatcher"
     class = "org.apache.shiro.authc.credential.HashedCredentialsMatcher" >
     <property name= "hashAlgorithmName"  value= "md5"  />
     <property name= "hashIterations"  value= "1"  />
</bean>
<!-- 緩存管理器 -->
<bean id= "cacheManager"  class = "org.apache.shiro.cache.ehcache.EhCacheManager" >
         <property name= "cacheManagerConfigFile"  value= "classpath:shiro-ehcache.xml" />
     </bean>
</beans>

提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)

免費(fèi)課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 福利理论片午夜片 | 久久综合九色综合网站 | 国产精品亚洲午夜一区二区三区 | 深夜免费在线观看 | 日韩国产午夜一区二区三区 | 午夜爱爱小视频 | www.四色.com| 女全身裸无遮挡免费毛片 | 成年视频在线观看免费 | 99热视热频这里只有精品 | 91精品麻豆| 日韩免费高清一级毛片 | 免费看黄在线观看 | 国产午夜精品久久理论片小说 | 日韩久久中文字幕 | 日韩欧美无线在码 | 欧美性猛交xx免费看 | 玖玖玖精品视频免费播放 | 国产精品视频网站 | 韩国精品videosex性韩国 | 国产成人不卡亚洲精品91 | 高清freexxxx性| 欧美中文在线视频 | 手机看日韩| 国产99在线播放免费 | 日韩在线小视频 | 国产一级片免费视频 | 国产看片一区二区三区 | 一级a俄罗斯毛片免费 | 欧美日韩一 | 欧洲美女a视频一级毛片 | www激情| 欧美精品第1页www劲爆 | 在线观看免费黄视频 | 97青草香蕉依人在线播放 | 色视频线观看在线播放 | 国产精品久久久久9999 | 一道本在线免费视频 | 国产成人宗合 | 在线看片成人免费视频 | 老司机午夜精品 |