shiro實戰系列(二)之入門實戰續
下面講解基於實戰系列一,所以相關的java檔案獲取pom.xml及其log4j檔案同樣適用於本次講解。
一、Using Shiro
Using Shiro 現在我們的 SecurityManager 已經設定好並可以使用了,現在我們能夠開始做一些我們真正關心的事情——執行安 全操作。 當保護我們的應用程式時,我們對自己可能提出的最為相關的問題是“當前使用者是誰”或“當前使用者是否被允許做 XXX”。當我們編寫程式碼或設計使用者介面時,問這些問題是很常見的:應用程式通常是基於使用者的背景情況建立的, 且你想基於每個使用者標準體現(保障)功能。因此,對於我們考慮應用程式安全的最自然的方式是基於當前使用者。 Shiro 的 API 使用它的 Subject 概念從根本上代表了“當前使用者”的概念。
幾乎在所有的環境中,你可以通過下面的呼叫獲取當前正在執行的使用者:
Subject currentUser=SecurityUtils.getSubject();
使用 SecurityUtils.getSubject(),我們可以獲得當前正在執行的 Subject。Subject 是一個安全術語,它基本上的意思是 “當前正在執行的使用者的特定的安全檢視”。它並沒有被稱為”User”是因為”User”一詞通常和人類相關聯。在安全 界,術語”Subject”可以表示為人類,而且可是第三方程式,cron job,daemon account,或其他類似的東西。它僅僅 意味著“該事物目前正與軟體互動”。對於大多數的意圖和目的,你可以把 Subject 看成是 Shiro 的”User”概念。
getSubject()在一個獨立的應用程式中呼叫,可以返回一個在應用程式特定位置的基於使用者資料的 Subject,並且在服 務器環境中(例如,Web 應用程式),它獲取的 Subject 是基於關聯了當前執行緒或傳入請求的使用者資料的。
二、現在你擁有了一個 Subject,你能拿它來做什麼?
如果你想在應用程式的當前會話中使事物對於使用者可用,你可以獲得他們的會話:
Session session = currentUser.getSession();
session.setAttribute("someKey", "aValue");
Session 是一個 Shiro 的特定例項,它提供了大部分你經常與 HttpSessoins 使用的東西,除了一些額外的好處以及一 個巨大的區別:它不需要一個 HTTP 環境! 如果在一個 Web 應用程式內部部署,預設的 Session 將會是基於 HttpSession 的。但在一個非 Web 環境中,像這個簡單的教程應用程式,Shiro 將會預設自動地使用它的 Enterprise Session Management。這意味著你會使用相同的 API 在你的應用程式,在任何層,不論部署環境!這開闢了應用程式的新世界,由於任何需要會話的應用程式不必 再被強制使用 HttpSession 或 EJB Stateful Session Beans。並且,任何客戶端技術現在能夠共享會話資料。
三、因此,現在你能獲取一個 Subject 以及他們的 Session。如果他們被允許做某些事,如對角色和許可權的檢查,像“檢 查”真正有用的地方在哪呢?
嗯,我們只能為一個已知的使用者做這些檢查。我們上面的 Subject 例項代表了當前使用者,但誰又是當前使用者?呃, 他們是匿名的——也就是說,直到直到他們至少登入一次。那麼,讓我像下面這樣做:
if(!currentUser.isAuthenticated()) { UsernamePasswordToken token = new UsernamePasswordToken("lonestarr","vespa"); token.setRememberMe(true); try { currentUser.login(token); } catch (UnknownAccountException e) { // TODO: handle exception log.info("there is no user with username of"+token.getPrincipal()); }catch (IncorrectCredentialsException e) { // TODO: handle exception log.info("Password for account"+token.getPrincipal()+"was incorrect"); }catch (LockedAccountException e) { // TODO: handle exception log.info("The account for username"+token.getPrincipal()+"is locked."+"Please contact your adminstrator to unlock it."); } }
比方說,
他們是是誰:
log.info("User["+currentUser.getPrincipal()+"]"+"logged in successfully");
判斷他們是否有特定的角色:
if(currentUser.hasRole("schwartz")) { log.info("May the schwartz be with you!"); }else { log.info("Hello,mere mortal"); }
還可以判斷他們是否有許可權在一個確定型別的實體上進行操作:
if(currentUser.isPermitted("winnebego:drive:eagle5")) { log.info("You are permitted to `drive` the winnebago with license plate (id) `eagle5` . " + "Here are the keys - have fun!"); }else { log.info("Sorry,you aren`t allowed to drive the `eagle5` winnebago"); }
最後,當使用者完成了對應用程式的使用,他們可以登出:
currentUser.logout();
以上程式碼完全版如下所示:
import org.apache.log4j.Logger; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.LockedAccountException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.session.Session; import org.apache.shiro.util.Factory; public class Tutorial { private static Logger log = Logger.getLogger(Tutorial.class); public static void main(String[] args) { log.info("My First Apache Shiro Application"); Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); org.apache.shiro.subject.Subject currentUser = SecurityUtils.getSubject(); Session session = currentUser.getSession(); session.setAttribute("someKey", "aValue"); String value = (String) session.getAttribute("someKey"); if(value.equals("aValue")) { log.info("Retrieved the correct value!["+value+"]"); } if(!currentUser.isAuthenticated()) { UsernamePasswordToken token = new UsernamePasswordToken("lonestarr","vespa"); token.setRememberMe(true); try { currentUser.login(token); } catch (UnknownAccountException e) { // TODO: handle exception log.info("there is no user with username of"+token.getPrincipal()); }catch (IncorrectCredentialsException e) { // TODO: handle exception log.info("Password for account"+token.getPrincipal()+"was incorrect"); }catch (LockedAccountException e) { // TODO: handle exception log.info("The account for username"+token.getPrincipal()+"is locked."+"Please contact your adminstrator to unlock it."); } } log.info("User["+currentUser.getPrincipal()+"]"+"logged in successfully"); //test a role if(currentUser.hasRole("schwartz")) { log.info("May the schwartz be with you!"); }else { log.info("Hello,mere mortal"); } if(currentUser.isPermitted("winnebego:drive:eagle5")) { log.info("You are permitted to `drive` the winnebago with license plate (id) `eagle5` . " + "Here are the keys - have fun!"); }else { log.info("Sorry,you aren`t allowed to drive the `eagle5` winnebago"); } currentUser.logout(); System.exit(0); } }
以上是完整的示例說明如下:
從建立工廠載入配置檔案shiro.init到建立安全管理器,到獲取當前使用者,到用sesion儲存使用者例項。
再到獲取使用者例項及其獲取使用者角色及其相應許可權
相關文章
- ElasticSearch實戰系列六: Logstash快速入門和實戰Elasticsearch
- 逆向入門分析實戰(二)
- webpack 快速入門 系列 —— 實戰一Web
- OpenFaaS實戰之二:函式入門函式
- 小程式從入門到實戰系列(一)
- podman 入門實戰
- React實戰入門指南React
- Flutter For Web入門實戰FlutterWeb
- Linux入門到實戰Linux
- Java Agent入門實戰(二)-Instrumentation原始碼概述Java原始碼
- Elasticsearch 入門實戰(9)--Java API Client 使用二ElasticsearchJavaAPIclient
- Docker 實戰教程之從入門到提高(二)Docker
- Python爬蟲入門實戰之貓眼電影資料抓取(實戰篇)Python爬蟲
- 指令碼之美│VBS 入門互動實戰指令碼
- Selenium實戰教程系列(二)—元素定位
- Selenium實戰教程系列(二)---元素定位
- 小程式入門到實戰(二)--案例原始碼分享原始碼
- Elasticsearch 入門實戰(8)--REST API 使用二(Search API)ElasticsearchRESTAPI
- Flutter 入門與實戰(二):容器的盒子模型Flutter模型
- Redis 從入門到實戰Redis
- Gin + GORM 入門到實戰GoORM
- Locust 從入門到實戰
- 持續整合之 Spring Boot 實戰篇Spring Boot
- 域滲透之ATT&CK實戰系列——紅隊實戰(一)
- 入門Python資料分析最好的實戰專案(二)Python
- 滲透測試入門實戰
- Docker從入門到實戰pdfDocker
- Android中的JNI入門實戰Android
- Docker實戰-從入門到跑路Docker
- Spring Security 入門原理及實戰Spring
- Docker入門實戰 (四) - Docker NetworkDocker
- Pulsar 入門實戰(6)--Rest APIRESTAPI
- Pulsar 入門實戰(3)--安裝
- 《Flink入門與實戰》簡介
- 深度學習:TensorFlow入門實戰深度學習
- Gulp4.0入門和實戰
- Pytorch實戰入門(一):搭建MLPPyTorch
- 大資料系列零基礎由入門到實戰大資料