丁香五月亚洲,日女人在线,太阳城色网,韩日AV在线秒放

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

前言

本文主要講解的知識點(diǎn)有以下:

  • 權(quán)限管理的基礎(chǔ)知識
  • 模型
  • 粗粒度和細(xì)粒度的概念
  • 回顧URL攔截的實(shí)現(xiàn)
  • Shiro的介紹與簡單入門

一、Shiro基礎(chǔ)知識

在學(xué)習(xí)Shiro這個(gè)框架之前,首先我們要先了解Shiro需要的基礎(chǔ)知識:權(quán)限管理

1.1什么是權(quán)限管理?

只要有用戶參與的系統(tǒng)一般都要有權(quán)限管理,權(quán)限管理實(shí)現(xiàn)對用戶訪問系統(tǒng)的控制,按照安全規(guī)則或者安全策略控制用戶可以訪問而且只能訪問自己被授權(quán)的資源。

對權(quán)限的管理又分為兩大類別:

  • 用戶認(rèn)證
  • 用戶授權(quán)

1.1.1用戶認(rèn)證

用戶認(rèn)證,用戶去訪問系統(tǒng),系統(tǒng)要驗(yàn)證用戶身份的合法性

最常用的用戶身份驗(yàn)證的方法:1、用戶名密碼方式、2、指紋打卡機(jī)、3、基于證書驗(yàn)證方法。。系統(tǒng)驗(yàn)證用戶身份合法,用戶方可訪問系統(tǒng)的資源。

舉個(gè)例子:

  • 當(dāng)我們輸入了自己的淘寶的賬戶和密碼,才能打開購物車

用戶認(rèn)證的流程:

  • 判斷該資源能否不認(rèn)證就能訪問【登陸頁面、首頁】
  • 如果該資源需要認(rèn)證后才能訪問,那么判斷該訪問者是否認(rèn)證了
  • 如果還沒有認(rèn)證,那么需要返回到【登陸頁面】進(jìn)行認(rèn)證
  • 認(rèn)證通過后才能訪問資源

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

從用戶認(rèn)證我們可以抽取出這么幾個(gè)概念

  • subject主體:理解為用戶,可能是程序,都要去訪問系統(tǒng)的資源,系統(tǒng)需要對subject進(jìn)行身份認(rèn)證
  • principal身份信息:通常是唯一的,一個(gè)主體還有多個(gè)身份信息,但是都有一個(gè)主身份信息(primary principal)【我們可以選擇身份證認(rèn)證、學(xué)生證認(rèn)證等等都是我們的身份信息】
  • credential憑證信息:可以是密碼 、證書、指紋。

總結(jié):主體在進(jìn)行身份認(rèn)證時(shí)需要提供身份信息和憑證信息。

1.1.2用戶授權(quán)

用戶授權(quán),簡單理解為訪問控制,在用戶認(rèn)證通過后,系統(tǒng)對用戶訪問資源進(jìn)行控制,用戶具有資源的訪問權(quán)限方可訪問。

用戶授權(quán)的流程

  • 到達(dá)了用戶授權(quán)環(huán)節(jié),當(dāng)然是需要用戶認(rèn)證之后了
  • 用戶訪問資源,系統(tǒng)判斷該用戶是否有權(quán)限去操作該資源
  • 如果該用戶有權(quán)限才能夠訪問,如果沒有權(quán)限就不能訪問了

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

授權(quán)的過程可以簡單理解為:主體認(rèn)證之后,系統(tǒng)進(jìn)行訪問控制

subject必須具備資源的訪問權(quán)限才可訪問該資源..

權(quán)限/許可(permission) :針對資源的權(quán)限或許可,subject具有permission訪問資源,如何訪問/操作需要定義permission,權(quán)限比如:用戶添加、用戶修改、商品刪除

資源可以分為兩種

  • 資源類型:系統(tǒng)的用戶信息就是資源類型,相當(dāng)于java類。
  • 資源實(shí)例:系統(tǒng)中id為001的用戶就是資源實(shí)例,相當(dāng)于new的java對象。

1.2權(quán)限管理模型

一般地,我們可以抽取出這么幾個(gè)模型:

  • 主體(賬號、密碼)
  • 資源(資源名稱、訪問地址)
  • 權(quán)限(權(quán)限名稱、資源id)
  • 角色(角色名稱)
  • 角色和權(quán)限關(guān)系(角色id、權(quán)限id)
  • 主體和角色關(guān)系(主體id、角色id)

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

通常企業(yè)開發(fā)中將資源和權(quán)限表合并為一張權(quán)限表,如下:

  • 資源(資源名稱、訪問地址)
  • 權(quán)限(權(quán)限名稱、資源id)

合并為:

  • 權(quán)限(權(quán)限名稱、資源名稱、資源訪問地址)

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

1.3分配權(quán)限

用戶需要分配相應(yīng)的權(quán)限才可訪問相應(yīng)的資源。權(quán)限是對于資源的操作許可。

通常給用戶分配資源權(quán)限需要將權(quán)限信息持久化,比如存儲在關(guān)系數(shù)據(jù)庫中。把用戶信息、權(quán)限管理、用戶分配的權(quán)限信息寫到數(shù)據(jù)庫(權(quán)限數(shù)據(jù)模型)

1.3.1基于角色訪問控制

RBAC(role based access control),基于角色的訪問控制。

//如果該user是部門經(jīng)理則可以訪問if中的代碼if(user.hasRole(\’部門經(jīng)理\’)){ //系統(tǒng)資源內(nèi)容 //用戶報(bào)表查看}

角色針對人劃分的,人作為用戶在系統(tǒng)中屬于活動內(nèi)容,如果該 角色可以訪問的資源出現(xiàn)變更,需要修改你的代碼了,

if(user.hasRole(\’部門經(jīng)理\’) || user.hasRole(\’總經(jīng)理\’) ){ //系統(tǒng)資源內(nèi)容 //用戶報(bào)表查看}

基于角色的訪問控制是不利于系統(tǒng)維護(hù)(可擴(kuò)展性不強(qiáng))。

1.3.2基于資源的訪問控制

RBAC(Resource based access control),基于資源的訪問控制。

資源在系統(tǒng)中是不變的,比如資源有:類中的方法,頁面中的按鈕。

對資源的訪問需要具有permission權(quán)限,代碼可以寫為:if(user.hasPermission (\’用戶報(bào)表查看(權(quán)限標(biāo)識符)\’)){ //系統(tǒng)資源內(nèi)容 //用戶報(bào)表查看}

建議使用基于資源的訪問控制實(shí)現(xiàn)權(quán)限管理


二、 粗粒度和細(xì)粒度權(quán)限

細(xì)粒度權(quán)限管理:對資源實(shí)例的權(quán)限管理。資源實(shí)例就資源類型的具體化,比如:用戶id為001的修改連接,1110班的用戶信息、行政部的員工。細(xì)粒度權(quán)限管理就是數(shù)據(jù)級別的權(quán)限管理。

粗粒度權(quán)限管理比如:超級管理員可以訪問戶添加頁面、用戶信息等全部頁面。部門管理員可以訪問用戶信息頁面包括 頁面中所有按鈕。

粗粒度和細(xì)粒度例子

系統(tǒng)有一個(gè)用戶列表查詢頁面,對用戶列表查詢分權(quán)限,如果粗顆粒管理,張三和李四都有用戶列表查詢的權(quán)限,張三和李四都可以訪問用戶列表查詢。進(jìn)一步進(jìn)行細(xì)顆粒管理,張三(行政部)和李四(開發(fā)部)只可以查詢自己本部門的用戶信息。張三只能查看行政部 的用戶信息,李四只能查看開發(fā)部門的用戶信息。細(xì)粒度權(quán)限管理就是數(shù)據(jù)級別的權(quán)限管理。

2.1如何實(shí)現(xiàn)粗粒度權(quán)限管理?

粗粒度權(quán)限管理比較容易將權(quán)限管理的代碼抽取出來在系統(tǒng)架構(gòu)級別統(tǒng)一處理。比如:通過springmvc的攔截器實(shí)現(xiàn)授權(quán)。

對細(xì)粒度權(quán)限管理在數(shù)據(jù)級別是沒有共性可言,針對細(xì)粒度權(quán)限管理就是系統(tǒng)業(yè)務(wù)邏輯的一部分,在業(yè)務(wù)層去處理相對比較簡單

比如:部門經(jīng)理只查詢本部門員工信息,在service接口提供一個(gè)部門id的參數(shù),controller中根據(jù)當(dāng)前用戶的信息得到該 用戶屬于哪個(gè)部門,調(diào)用service時(shí)將部門id傳入service,實(shí)現(xiàn)該用戶只查詢本部門的員工。

2.1.1基于URL攔截

基于url攔截的方式實(shí)現(xiàn)在實(shí)際開發(fā)中比較常用的一種方式。

對于web系統(tǒng),通過filter過慮器實(shí)現(xiàn)url攔截,也可以springmvc的攔截器實(shí)現(xiàn)基于url的攔截。

2.2.2使用權(quán)限管理框架實(shí)現(xiàn)

對于粗粒度權(quán)限管理,建議使用優(yōu)秀權(quán)限管理框架來實(shí)現(xiàn),節(jié)省開發(fā)成功,提高開發(fā)效率。

shiro就是一個(gè)優(yōu)秀權(quán)限管理框架。

三、回顧URL攔截

我們在學(xué)習(xí)的路途上也是使用過幾次URL對權(quán)限進(jìn)行攔截的

當(dāng)時(shí)我們做了權(quán)限的增刪該查的管理系統(tǒng),但是在權(quán)限表中是沒有把資源添加進(jìn)去,我們使用的是Map集合來進(jìn)行替代的。

http://blog.csdn.net/hon_3y/article/details/61926175

隨后,我們學(xué)習(xí)了動態(tài)代理和注解,我們也做了一個(gè)基于注解的攔截

  • 在Controller得到service對象的時(shí)候,service工廠返回的是一個(gè)動態(tài)代理對象回去
  • Controller拿著代理對象去調(diào)用方法,代理對象就會去解析該方法上是否有注解
  • 如果有注解,那么就需要我們進(jìn)行判斷該主體是否認(rèn)證了,如果認(rèn)證了就判斷該主體是否有權(quán)限
  • 當(dāng)我們解析出該主體的權(quán)限和我們注解的權(quán)限是一致的時(shí)候,才放行!

http://blog.csdn.net/hon_3y/article/details/70767050

流程:

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

3.1認(rèn)證的JavaBean

我們之前認(rèn)證都是放在默認(rèn)的Javabean對象上的,現(xiàn)在既然我們準(zhǔn)備學(xué)Shiro了,我們就得專業(yè)一點(diǎn),弄一個(gè)專門存儲認(rèn)證信息的JavaBean

/** * 用戶身份信息,存入session 由于tomcat將session會序列化在本地硬盤上,所以使用Serializable接口 * * @author Thinkpad * */public class ActiveUser implements java.io.Serializable { private String userid;//用戶id(主鍵) private String usercode;// 用戶賬號 private String username;// 用戶名稱 private List<SysPermission> menus;// 菜單 private List<SysPermission> permissions;// 權(quán)限 // 省略get和set方法}

認(rèn)證的服務(wù)

@Override public ActiveUser authenticat(String userCode, String password) throws Exception { /** 認(rèn)證過程: 根據(jù)用戶身份(賬號)查詢數(shù)據(jù)庫,如果查詢不到用戶不存在 對輸入的密碼 和數(shù)據(jù)庫密碼 進(jìn)行比對,如果一致,認(rèn)證通過 */ //根據(jù)用戶賬號查詢數(shù)據(jù)庫 SysUser sysUser = this.findSysUserByUserCode(userCode); if(sysUser == null){ //拋出異常 throw new CustomException(\”用戶賬號不存在\”); } //數(shù)據(jù)庫密碼 (md5密碼 ) String password_db = sysUser.getPassword(); //對輸入的密碼 和數(shù)據(jù)庫密碼 進(jìn)行比對,如果一致,認(rèn)證通過 //對頁面輸入的密碼 進(jìn)行md5加密 String password_input_md5 = new MD5().getMD5ofStr(password); if(!password_input_md5.equalsIgnoreCase(password_db)){ //拋出異常 throw new CustomException(\”用戶名或密碼 錯(cuò)誤\”); } //得到用戶id String userid = sysUser.getId(); //根據(jù)用戶id查詢菜單 List<SysPermission> menus =this.findMenuListByUserId(userid); //根據(jù)用戶id查詢權(quán)限url List<SysPermission> permissions = this.findPermissionListByUserId(userid); //認(rèn)證通過,返回用戶身份信息 ActiveUser activeUser = new ActiveUser(); activeUser.setUserid(sysUser.getId()); activeUser.setUsercode(userCode); activeUser.setUsername(sysUser.getUsername());//用戶名稱 //放入權(quán)限范圍的菜單和url activeUser.setMenus(menus); activeUser.setPermissions(permissions); return activeUser; }

Controller處理認(rèn)證,如果身份認(rèn)證成功,那么把認(rèn)證信息存儲在Session中

@requestMapping(\”/login\”) public String login(HttpSession session, String randomcode,String usercode,String password)throws Exception{ //校驗(yàn)驗(yàn)證碼,防止惡性攻擊 //從session獲取正確驗(yàn)證碼 String validateCode = (String) session.getAttribute(\”validateCode\”); //輸入的驗(yàn)證和session中的驗(yàn)證進(jìn)行對比 if(!randomcode.equals(validateCode)){ //拋出異常 throw new CustomException(\”驗(yàn)證碼輸入錯(cuò)誤\”); } //調(diào)用service校驗(yàn)用戶賬號和密碼的正確性 ActiveUser activeUser = sysService.authenticat(usercode, password); //如果service校驗(yàn)通過,將用戶身份記錄到session session.setAttribute(\”activeUser\”, activeUser); //重定向到商品查詢頁面 return \”redirect:/first.action\”; }

身份認(rèn)證攔截器

//在執(zhí)行handler之前來執(zhí)行的 //用于用戶認(rèn)證校驗(yàn)、用戶權(quán)限校驗(yàn) @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //得到請求的url String url = request.getRequestURI(); //判斷是否是公開 地址 //實(shí)際開發(fā)中需要公開 地址配置在配置文件中 //從配置中取逆名訪問url List<String> open_urls = ResourcesUtil.gekeyList(\”anonymousURL\”); //遍歷公開 地址,如果是公開 地址則放行 for(String open_url:open_urls){ if(url.indexOf(open_url)>=0){ //如果是公開 地址則放行 return true; } } //判斷用戶身份在session中是否存在 HttpSession session = request.getSession(); ActiveUser activeUser = (ActiveUser) session.getAttribute(\”activeUser\”); //如果用戶身份在session中存在放行 if(activeUser!=null){ return true; } //執(zhí)行到這里攔截,跳轉(zhuǎn)到登陸頁面,用戶進(jìn)行身份認(rèn)證 request.getRequestDispatcher(\”/WEB-INF/jsp/login.jsp\”).forward(request, response); //如果返回false表示攔截不繼續(xù)執(zhí)行handler,如果返回true表示放行 return false; }

授權(quán)攔截器

//在執(zhí)行handler之前來執(zhí)行的 //用于用戶認(rèn)證校驗(yàn)、用戶權(quán)限校驗(yàn) @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //得到請求的url String url = request.getRequestURI(); //判斷是否是公開 地址 //實(shí)際開發(fā)中需要公開 地址配置在配置文件中 //從配置中取逆名訪問url List<String> open_urls = ResourcesUtil.gekeyList(\”anonymousURL\”); //遍歷公開 地址,如果是公開 地址則放行 for(String open_url:open_urls){ if(url.indexOf(open_url)>=0){ //如果是公開 地址則放行 return true; } } //從配置文件中獲取公共訪問地址 List<String> common_urls = ResourcesUtil.gekeyList(\”commonURL\”); //遍歷公用 地址,如果是公用 地址則放行 for(String common_url:common_urls){ if(url.indexOf(common_url)>=0){ //如果是公開 地址則放行 return true; } } //獲取session HttpSession session = request.getSession(); ActiveUser activeUser = (ActiveUser) session.getAttribute(\”activeUser\”); //從session中取權(quán)限范圍的url List<SysPermission> permissions = activeUser.getPermissions(); for(SysPermission sysPermission:permissions){ //權(quán)限的url String permission_url = sysPermission.getUrl(); if(url.indexOf(permission_url)>=0){ //如果是權(quán)限的url 地址則放行 return true; } } //執(zhí)行到這里攔截,跳轉(zhuǎn)到無權(quán)訪問的提示頁面 request.getRequestDispatcher(\”/WEB-INF/jsp/refuse.jsp\”).forward(request, response); //如果返回false表示攔截不繼續(xù)執(zhí)行handler,如果返回true表示放行 return false; }

攔截器配置:

<!–攔截器 –> <mvc:interceptors> <mvc:interceptor> <!– 用戶認(rèn)證攔截 –> <mvc:mapping path=\”/**\” /> <bean class=\”cn.itcast.ssm.controller.interceptor.Logininterceptor\”></bean> </mvc:interceptor> <mvc:interceptor> <!– 授權(quán)攔截 –> <mvc:mapping path=\”/**\” /> <bean class=\”cn.itcast.ssm.controller.interceptor.PermissionInterceptor\”></bean> </mvc:interceptor> </mvc:interceptors>

四、什么是Shiro

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

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

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

Shiro架構(gòu):

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

  • subject:主體,可以是用戶也可以是程序,主體要訪問系統(tǒng),系統(tǒng)需要對主體進(jìn)行認(rèn)證、授權(quán)。
  • securityManager:安全管理器,主體進(jìn)行認(rèn)證和授權(quán)都 是通過securityManager進(jìn)行。
  • authenticator:認(rèn)證器,主體進(jìn)行認(rèn)證最終通過authenticator進(jìn)行的。
  • authorizer:授權(quán)器,主體進(jìn)行授權(quán)最終通過authorizer進(jìn)行的。
  • sessionManager:web應(yīng)用中一般是用web容器對session進(jìn)行管理,shiro也提供一套session管理的方式。
  • SessionDao: 通過SessionDao管理session數(shù)據(jù),針對個(gè)性化的session數(shù)據(jù)存儲需要使用sessionDao。
  • cache Manager:緩存管理器,主要對session和授權(quán)數(shù)據(jù)進(jìn)行緩存,比如將授權(quán)數(shù)據(jù)通過cacheManager進(jìn)行緩存管理,和ehcache整合對緩存數(shù)據(jù)進(jìn)行管理。
  • realm:域,領(lǐng)域,相當(dāng)于數(shù)據(jù)源,通過realm存取認(rèn)證、授權(quán)相關(guān)數(shù)據(jù)。

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

  • 比如md5散列算法。

五、為什么使用Shiro

我們在使用URL攔截的時(shí)候,要將所有的URL都配置起來,繁瑣、不易維護(hù)

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

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

六、Shiro認(rèn)證

6.1導(dǎo)入jar包

我們使用的是Maven的坐標(biāo)就行了

<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-quartz</artifactId> <version>1.2.3</version> </dependency>

當(dāng)然了,我們也可以把Shiro相關(guān)的jar包全部導(dǎo)入進(jìn)去

<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.3</version></dependency>

6.2Shiro認(rèn)證流程

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

6.2.1通過配置文件創(chuàng)建工廠

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

// 用戶登陸和退出 @Test public void testLoginAndLogout() { // 創(chuàng)建securityManager工廠,通過ini配置文件創(chuàng)建securityManager工廠 factory<SecurityManager> factory = new IniSecurityManagerFactory( \”classpath:shiro-first.ini\”); // 創(chuàng)建SecurityManager SecurityManager securityManager = factory.getInstance(); // 將securityManager設(shè)置當(dāng)前的運(yùn)行環(huán)境中 SecurityUtils.setSecurityManager(securityManager); // 從SecurityUtils里邊創(chuàng)建一個(gè)subject Subject subject = SecurityUtils.getSubject(); // 在認(rèn)證提交前準(zhǔn)備token(令牌) // 這里的賬號和密碼 將來是由用戶輸入進(jìn)去 UsernamePasswordToken token = new UsernamePasswordToken(\”zhangsan\”, \”111111\”); try { // 執(zhí)行認(rèn)證提交 subject.login(token); } catch (AuthenticationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 是否認(rèn)證通過 boolean isAuthenticated = subject.isAuthenticated(); System.out.println(\”是否認(rèn)證通過:\” isAuthenticated); // 退出操作 subject.logout(); // 是否認(rèn)證通過 isAuthenticated = subject.isAuthenticated(); System.out.println(\”是否認(rèn)證通過:\” isAuthenticated); }

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

6.3小結(jié)

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

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

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

6.4自定義realm

從第一個(gè)認(rèn)證程序我們可以看見,我們所說的流程,是認(rèn)證器去找realm去查詢我們相對應(yīng)的數(shù)據(jù)。而默認(rèn)的realm是直接去與配置文件來比對的,一般地,我們在開發(fā)中都是讓realm去數(shù)據(jù)庫中比對。

因此,我們需要自定義realm

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

public class CustomRealm extends AuthorizingRealm { // 設(shè)置realm的名稱 @Override public void setName(String name) { super.setName(\”customRealm\”); } // 用于認(rèn)證 @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { // token是用戶輸入的 // 第一步從token中取出身份信息 String userCode = (String) token.getPrincipal(); // 第二步:根據(jù)用戶輸入的userCode從數(shù)據(jù)庫查詢 // …. // 如果查詢不到返回null //數(shù)據(jù)庫中用戶賬號是zhangsansan /*if(!userCode.equals(\”zhangsansan\”)){// return null; }*/ // 模擬從數(shù)據(jù)庫查詢到密碼 String password = \”111112\”; // 如果查詢到返回認(rèn)證信息AuthenticationInfo SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo( userCode, password, this.getName()); return simpleAuthenticationInfo; } // 用于授權(quán) @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { // TODO Auto-generated method stub return null; }}

6.5配置realm

需要在shiro-realm.ini配置realm注入到securityManager中。

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

6.6測試自定義realm

同上邊的入門程序,需要更改ini配置文件路徑:

同上邊的入門程序,需要更改ini配置文件路徑:Factory<SecurityManager> factory = new IniSecurityManagerFactory( \”classpath:shiro-realm.ini\”);

6.7散列算法

我們?nèi)绻續(xù)d5,我們就會知道m(xù)d5是不可逆的,但是如果設(shè)置了一些安全性比較低的密碼:111111…即時(shí)是不可逆的,但還是可以通過暴力算法來得到md5對應(yīng)的明文…

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

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

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

測試:

public class MD5Test { public static void main(String[] args) { //原始 密碼 String source = \”111111\”; //鹽 String salt = \”qwerty\”; //散列次數(shù) int hashIterations = 2; //上邊散列1次:f3694f162729b7d0254c6e40260bf15c //上邊散列2次:36f2dfa24d0a9fa97276abbe13e596fc //構(gòu)造方法中: //第一個(gè)參數(shù):明文,原始密碼 //第二個(gè)參數(shù):鹽,通過使用隨機(jī)數(shù) //第三個(gè)參數(shù):散列的次數(shù),比如散列兩次,相當(dāng) 于md5(md5(\’\’)) Md5Hash md5Hash = new Md5Hash(source, salt, hashIterations); String password_md5 = md5Hash.toString(); System.out.println(password_md5); //第一個(gè)參數(shù):散列算法 SimpleHash simpleHash = new SimpleHash(\”md5\”, source, salt, hashIterations); System.out.println(simpleHash.toString()); }}

6.8自定義realm支持md5

自定義realm

public class CustomRealmMd5 extends AuthorizingRealm { // 設(shè)置realm的名稱 @Override public void setName(String name) { super.setName(\”customRealmMd5\”); } // 用于認(rèn)證 @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { // token是用戶輸入的 // 第一步從token中取出身份信息 String userCode = (String) token.getPrincipal(); // 第二步:根據(jù)用戶輸入的userCode從數(shù)據(jù)庫查詢 // …. // 如果查詢不到返回null // 數(shù)據(jù)庫中用戶賬號是zhangsansan /* * if(!userCode.equals(\”zhangsansan\”)){// return null; } */ // 模擬從數(shù)據(jù)庫查詢到密碼,散列值 String password = \”f3694f162729b7d0254c6e40260bf15c\”; // 從數(shù)據(jù)庫獲取salt String salt = \”qwerty\”; //上邊散列值和鹽對應(yīng)的明文:111111 // 如果查詢到返回認(rèn)證信息AuthenticationInfo SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo( userCode, password, ByteSource.Util.bytes(salt), this.getName()); return simpleAuthenticationInfo; } // 用于授權(quán) @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { // TODO Auto-generated method stub return null; }}

配置文件:

一篇文章讀懂權(quán)限管理和shiro(權(quán)限與管理)

這里寫圖片描述

測試:

// 自定義realm實(shí)現(xiàn)散列值匹配 @Test public void testCustomRealmMd5() { // 創(chuàng)建securityManager工廠,通過ini配置文件創(chuàng)建securityManager工廠 Factory<SecurityManager> factory = new IniSecurityManagerFactory( \”classpath:shiro-realm-md5.ini\”); // 創(chuàng)建SecurityManager SecurityManager securityManager = factory.getInstance(); // 將securityManager設(shè)置當(dāng)前的運(yùn)行環(huán)境中 SecurityUtils.setSecurityManager(securityManager); // 從SecurityUtils里邊創(chuàng)建一個(gè)subject Subject subject = SecurityUtils.getSubject(); // 在認(rèn)證提交前準(zhǔn)備token(令牌) // 這里的賬號和密碼 將來是由用戶輸入進(jìn)去 UsernamePasswordToken token = new UsernamePasswordToken(\”zhangsan\”, \”222222\”); try { // 執(zhí)行認(rèn)證提交 subject.login(token); } catch (AuthenticationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 是否認(rèn)證通過 boolean isAuthenticated = subject.isAuthenticated(); System.out.println(\”是否認(rèn)證通過:\” isAuthenticated); }

七、總結(jié)

  • 用戶認(rèn)證和用戶授權(quán)是Shiro的基礎(chǔ),用戶認(rèn)證其實(shí)上就是登陸操作、用戶授權(quán)實(shí)際上就是對資源攔截的操作。
  • 權(quán)限管理的模型一般我們都將資源放在權(quán)限表中進(jìn)行管理起來。
  • 我們可以基于角色攔截,也可以基于資源攔截。要是基于角色攔截的話,那么如果角色的權(quán)限發(fā)生變化了,那就需要修改代碼了。推薦使用基于資源進(jìn)行攔截
  • 這次URL攔截,我們使用一個(gè)JavaBean來封裝所有的認(rèn)證信息。當(dāng)用戶登陸了之后,我們就把用戶對菜單欄的訪問、對資源的訪問權(quán)限都封裝到該JavaBean中
  • 當(dāng)使用攔截器進(jìn)行用戶認(rèn)證的時(shí)候,我們只要判斷Session域有沒有JavaBen對象即可了。
  • 當(dāng)時(shí)候攔截器進(jìn)行用戶授權(quán)的時(shí)候,我們要判斷JavaBean中的權(quán)限是否能夠訪問該資源。
  • 以前URL攔截的方式需要把所有的URL都在數(shù)據(jù)庫進(jìn)行管理。非常麻煩,不易維護(hù)。
  • 我們希望Shiro去認(rèn)證的時(shí)候是通過realm去數(shù)據(jù)庫查詢數(shù)據(jù)的。而我們r(jià)eaml默認(rèn)是查詢配置文件的數(shù)據(jù)的。
  • 因此,我們需要自定義reaml,使得它是去數(shù)據(jù)庫查詢數(shù)據(jù)。只要繼承AuthorizingRealm類就行了。
  • 當(dāng)然了,自定義后的reaml也需要在配置文件中寫上我們的自定義reaml的位置的。
  • 散列算法就是為了讓密碼不被別人給破解。我們可對原始的密碼加鹽再進(jìn)行散列,這就加大了破解的難度了。
  • 自定義的reaml也是支持散列算法的,相同的,還是需要我們在配置文件中配置一下就好了。

作者:Java3y原文:轉(zhuǎn)載自公眾號,Java3y,已獲作者授權(quán)

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。

(0)
上一篇 2022年12月2日 上午9:34
下一篇 2022年12月2日 上午9:48

相關(guān)推薦

  • 科研項(xiàng)目調(diào)研費(fèi)

    科研項(xiàng)目調(diào)研費(fèi) 科研項(xiàng)目調(diào)研費(fèi)是科研項(xiàng)目中不可或缺的一部分,用于進(jìn)行深入研究和了解用戶需求和反饋。調(diào)研費(fèi)的支付是由項(xiàng)目組根據(jù)具體需求和預(yù)算來決定的。 在實(shí)施調(diào)研計(jì)劃之前,項(xiàng)目組需要…

    科研百科 2025年3月5日
    2
  • 量化交易軟件大比拼:尋找你的投資利器(量化交易軟件app)

    在數(shù)字化時(shí)代,量化交易憑借其精準(zhǔn)的數(shù)據(jù)分析和高效的交易執(zhí)行,成為了投資市場的一股不可忽視的力量。然而,對于投資者而言,如何選擇一款適合自己的量化交易軟件,卻是一個(gè)值得深思的問題。本…

    科研百科 2024年5月16日
    77
  • 科研項(xiàng)目評審驗(yàn)收會主持詞科研項(xiàng)目評審驗(yàn)收會主持詞

    科研項(xiàng)目評審驗(yàn)收會主持詞 尊敬的各位專家、各位來賓,大家好! 今天,我們歡聚一堂,舉行科研項(xiàng)目評審驗(yàn)收會,共同驗(yàn)收一批優(yōu)秀的科研項(xiàng)目。我代表主辦方,向各位專家和來賓表示熱烈的歡迎!…

    科研百科 2024年6月18日
    81
  • 國開建筑工程項(xiàng)目管理作業(yè)1

    國開建筑工程項(xiàng)目管理作業(yè)1 建筑行業(yè)是一個(gè)涉及到眾多細(xì)節(jié)和環(huán)節(jié)的行業(yè),而建筑工程項(xiàng)目管理是其中最為重要的一個(gè)環(huán)節(jié)。一個(gè)高效的建筑工程項(xiàng)目管理需要科學(xué)的流程、高效的團(tuán)隊(duì)協(xié)作、嚴(yán)格的質(zhì)…

    科研百科 2024年8月19日
    4
  • 政府項(xiàng)目管理軟件

    政府項(xiàng)目管理軟件:創(chuàng)新管理工具助力政府更高效地組織項(xiàng)目 政府項(xiàng)目管理軟件是一種能夠幫助政府組織管理項(xiàng)目的工具,它通過提供全面的項(xiàng)目計(jì)劃、控制、協(xié)調(diào)和報(bào)告功能,幫助政府項(xiàng)目管理人員更…

    科研百科 2024年7月22日
    2
  • 建行臨沂市分行營業(yè)部:內(nèi)控合規(guī)學(xué)習(xí)心得(內(nèi)控合規(guī)心得體會銀行)

    魯網(wǎng)6月16日訊 今年以來,建設(shè)銀行臨沂市分行營業(yè)部合規(guī)經(jīng)營扎實(shí)推進(jìn)行內(nèi)定期開展的內(nèi)控合規(guī)學(xué)習(xí),進(jìn)一步加強(qiáng)員工對合規(guī)意義的理解。 合規(guī)經(jīng)營是防范商業(yè)銀行操作風(fēng)險(xiǎn)的需要。合規(guī)經(jīng)營是規(guī)…

    科研百科 2024年1月23日
    122
  • 項(xiàng)目管理工具excel

    項(xiàng)目管理工具Excel:輕松管理項(xiàng)目進(jìn)度、成本和風(fēng)險(xiǎn) 隨著現(xiàn)代數(shù)字化時(shí)代的到來,越來越多的公司和組織開始使用項(xiàng)目管理工具來幫助他們管理項(xiàng)目。其中,Excel作為常用的項(xiàng)目管理工具之…

    科研百科 2024年7月28日
    1
  • 工程項(xiàng)目管理的國內(nèi)外背景

    工程項(xiàng)目管理是一個(gè)涉及到眾多因素的領(lǐng)域,包括項(xiàng)目管理的方法論、工具和技術(shù),以及項(xiàng)目團(tuán)隊(duì)成員的技能和經(jīng)驗(yàn)。在國內(nèi)和國外,工程項(xiàng)目管理面臨著截然不同的背景和挑戰(zhàn)。 在國內(nèi),工程項(xiàng)目管理…

    科研百科 2024年8月19日
    4
  • 科研項(xiàng)目工程化

    科研項(xiàng)目工程化:挑戰(zhàn)與機(jī)遇 近年來,隨著科技的不斷進(jìn)步,科研項(xiàng)目的工程化已經(jīng)成為一個(gè)熱門話題。工程項(xiàng)目的工程化是指將科學(xué)研究轉(zhuǎn)化為實(shí)際應(yīng)用,通過將科學(xué)理論和技術(shù)方法轉(zhuǎn)化為可操作的技…

    科研百科 2025年3月1日
    1
  • 成立內(nèi)控手冊編寫小組的通知怎么寫

    成立內(nèi)控手冊編寫小組的通知 尊敬的各位成員: 為了加強(qiáng)公司內(nèi)控管理,提高公司整體管理水平,公司決定成立內(nèi)控手冊編寫小組。該小組將會負(fù)責(zé)編寫公司的內(nèi)控手冊,該手冊將作為公司管理的重要…

    科研百科 2024年11月25日
    8
欧美日韩国产在线人成dvd| 字幕无码特黄大片中文| 国语自产精品视频在视频| 色五月丁香婷婷综合| 一本一本久久久精品综合不卡| 久久亚洲视频精品| 欧美性爱视频一区| 激情五月欧美| 午夜男女爽爽爽免费播放| 国产亚洲精品综合二区| 欧美日韩三级,色| 品久久久久| 国产成人无码网站| 亚洲综合天堂婷婷| 热热热热色色| 神啊久久网站| 一本久久A久久精品亚洲| 久久久精品首页| 亚洲欧美洲成人一区二区三区| 琪琪无码午夜精品久久久久| 下一篇亚洲3p| 91精品精品| 欧美国产日韩在线播放| 精品一区二区三区无码av毛片| av天堂中文在线| 国产精品白丝视频| 久久久久久久国产视频| 国产精品毛片无摭挡| 久久俺来也伊人| 最新亚洲免费色| 亚洲欧美在线不卡| 无码18毛片| 国内视频一区二区三区| 中文字幕国产专区99| 男人干女人网站免费看| 精品国欧很黄很黄的| 亚洲精品无码AV中文永久在线| 亚洲欧美日韩成人综合网| 在线精品999| 国产精品妇女高潮惨叫| 亚洲成人小说|