# 20. 10 Minute Tutorial 十分鐘教程
# 20. 10 Minute Tutorial 十分鐘教程
## Introduction 前言
歡迎來到 Apache Shiro 十分鐘教程!
希望通過這個簡單、快速的示例,可以讓你對應用程序中使用 Shiro 有個深入的了解。嗯,10分鐘你應該可以搞定它。
## Overview 概述
Apache Shiro 是什么?
Apache Shiro 一個功能強大,使用簡單的 Java 安全框架,它為開發人員提供一個直觀而全面的認證,授權,加密及會話管理的解決方案。
實際上,Shiro 的主要功能是管理應用程序中與安全相關的全部,同時盡可能支持多種實現方法。Shiro 是建立在完善的接口驅動設計和面向對象原則之上的,支持各種自定義行為。Shiro 提供的默認實現,使其能完成與其他安全框架同樣的功能,這不也是我們一直努力想要得到的嗎!
那么 Apache Shiro 能用來做什么呢?
很多,很多,嘿嘿。但是不在快速指南中做介紹,如果你想知道,那怎么辦呢?去[這里](http://shiro.apache.org/features.html)找尋你的答案吧。當然如果你還想知道我們什么時候,以及為什么要“創造”Shiro,去看看Shrio的[歷史和使命](http://shiro.apache.org/what-is-shiro.html)吧。
現在讓我們動手做點兒什么吧。
*Shiro可以在任何環境下運行,小到最簡單的命令行應用,大到大型的企業應用以及集群應用。但是我們準備在快速指南中使用最最簡單的 main 方法的方式,讓你對 Shiro 的API有個感官的認識。*
## Download 下載
1. 確保已經安裝了 JDK1.5+ 和 Maven2.2+
2. 去這里[下載](http://shiro.apache.org/download.html)最新已發布的源碼。例子中我們使用 1.1.0 發布版本。
3. 解壓源代碼
unzip shiro-root-1.2.0-source-release.zip
4. 進入快速指南文件夾
cd shiro-root-1.1.0/samples/quickstart
5. 運行快速指南
mvn compile exec:java
過程中會輸出日志信息,用來告訴你正在進行的是什么,最后退出執行。可以在這里 samples/quickstart/src/main/java/Quickstart.java 找到源碼,也可以進行修改,記得修改后運行 mvn compile exec:java 即可。
## Quickstart.java
Quickstart.java 中包含剛剛我們提到的所有內容(認證、授權等等),通過這個簡單的示例可以讓你輕松的熟悉Shiro的API。那么,讓我們把Quickstart.java中的代碼,一點一點剖析,這樣便于理解它們的作用。 幾乎所有的環境下,都可以通過這種方式獲取當前用戶:
```
Subject currentUser = SecurityUtils.getSubject();
```
通過 [SecurityUtils.getSubject()](http://shiro.apache.org/static/current/apidocs/org/apache/shiro/SecurityUtils.html),就可以獲取當前 [Subject](https://github.com/waylau/apache-shiro-1.2.x-reference/blob/master/IV.%20Auxiliary%20Support%20%E8%BE%85%E5%8A%A9%E6%94%AF%E6%8C%81/14.%20Custom%20Subjects%20%E8%87%AA%E5%AE%9A%E4%B9%89%20Subject.md)。Subject 是應用中用戶的一個特定安全的縮影,雖然感覺上直接使用 User 會更貼切,但是實際上它的意義遠遠超過了 User。而且每個應用程序都會有自己的用戶以及框架,我們可不想和它們混淆在一起,況且 Subject 就是安全領域公認的名詞。OK,我們繼續。
在單應用系統中,調用 getSubject() 會返回一個 Subject,它是位于應用程序中特定位置的用戶信息;在服務器中運行的情況下(比如web應用),getSubject 會返回一個位于當前線程或請求中的用戶信息。 現在你已經得到了 Subject 對象,那么用它可以做什么呢?
如果你想得到應用中用戶當前 Session 的其他參數,可以這樣獲取Session 對象:
```
Session session = currentUser.getSession();
session.setAttribute( "someKey", "aValue" );
```
這個Session 對象是Shiro中特有的對象,它和我們經常使用的HttpSession 非常相似,但還提供了額外的東西,其中與 HttpSession最大的不同就是 Shiro 中的 Session 不依賴 HTTP 環境(換句話說,可以在非 HTTP 容器下運行)。
如果將 Shiro 部署在 web 應用程序中,那么這個 Session 就是基于HttpSession 的。但是像 QuickStart 示例那樣,在非 web 環境下使用,Shiro 則默認使用 EnterpriseSessionManagment。也就是說,不論在應用中的任何一層使用同樣的API,卻不需要考慮部署環境,這一優點為應用打開一個全新的世界,因為應用中要獲取Session對象再也不用依賴于 HttpSession 或者 EJB 的會話 Bean。而且任何客戶端技術都可以共享 session 數據。
現在你可以得到當前 Subject 和它的 Session 對象。那么我們如何驗證比如角色和權限這些東西呢?
很簡單,可以通過已得到的 user 對象進行驗證。Subject 對象代表當前用戶,但是,誰才是當前用戶呢?他們可是匿名用戶啊。也就是說,必須登錄才能獲取到當前用戶。沒問題,這樣就可以搞定:
```
if ( !currentUser.isAuthenticated() ) {
//收集用戶的主要信息和憑據,來自GUI中的特定的方式
//如包含用戶名/密碼的HTML表格,X509證書,OpenID,等。
//我們將使用用戶名/密碼的例子因為它是最常見的。.
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
//支持'remember me' (無需配置,內建的!):
token.setRememberMe(true);
currentUser.login(token);
}
```
就是這樣,不能再簡單了。
但如果登錄失敗了呢,你可以捕獲所有異常然后按你期望的方式去處理:
```
try {
currentUser.login( token );
//無異常,說明就是我們想要的!
} catch ( UnknownAccountException uae ) {
//username 不存在,給個錯誤提示?
} catch ( IncorrectCredentialsException ice ) {
//password 不匹配,再輸入?
} catch ( LockedAccountException lae ) {
//賬號鎖住了,不能登入。給個提示?
}
... 更多類型異常 ...
} catch ( AuthenticationException ae ) {
//未考慮到的問題 - 錯誤?
}
```
這里有許多不同類別的異常你可以檢測到,也可以拋出你自己異常。詳見 [AuthenticationException JavaDoc](http://shiro.apache.org/static/current/apidocs/org/apache/shiro/authc/AuthenticationException.html)
*小貼士:*
*最好的方式是將普通的失敗信息反饋給用戶,你總不會希望幫助黑客來攻擊你的系統吧。*
好,到現在為止,我們有了一個登錄用戶,接下來我們還可以做什么?
讓我們顯示他們是誰
```
//打印主要信息 (本例子是 username):
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( "lightsaber:weild" ) ) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
```
同樣,我們還可以執行非常強大的 instance-level (實例級別)的權限檢測,檢測用戶是否具備訪問某個類型特定實例的權限:
```
if ( currentUser.isPermitted( "winnebago: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(); //清楚識別信息,設置 session 失效.
```
這些就是使用 Apache Shiro 開發應用的核心了,當然,Apache Shiro已將將很多復雜的東西封裝在內部了,但是現在它就是這么簡單。
你會有疑問吧,用戶登錄時,誰負責把用戶信息(用戶名、密碼、角色、權限等)取出來,還有運行時,誰負責安全認證呢?當然由你決定了啊。通過將一個實現了 Shiro 中的 [Realm](https://github.com/waylau/apache-shiro-1.2.x-reference/blob/master/II.%20Core%20%E6%A0%B8%E5%BF%83/7.%20Realms.md) 的 Reaml 配置到 Shiro 中即可。
至于如何配置很大程度上取決于你的運行時環境,比如在單應用、web 應用、基于 Spring 或 JEE 容器的應用或者組合模式中使用 Shiro,配置都有所不同。如何配置已經超出 QuickStart 示例的范圍,因為它的主要目的是幫助你熟悉 Shiro 的 API 和概念。
如果想進一步了解 Shiro,可以看看 [Authentication](https://github.com/waylau/apache-shiro-1.2.x-reference/blob/master/II.%20Core%20%E6%A0%B8%E5%BF%83/5.%20Authentication%20%E8%AE%A4%E8%AF%81.md) Guide 和 [Authorization](https://github.com/waylau/apache-shiro-1.2.x-reference/blob/master/II.%20Core%20%E6%A0%B8%E5%BF%83/6.%20Authorization%20%E6%8E%88%E6%9D%83.md) Guide。也可以查看其他[文檔](http://shiro.apache.org/documentation.html)(特別是 [用戶指南](https://github.com/waylau/apache-shiro-1.2.x-reference)),這里可以解決你的各種疑問。
感謝一路同行,希望你能喜歡使用 Apache Shiro。
*譯者注:*本文參考:<http://shiro.apache.org/10-minute-tutorial.html>。如果對本中文翻譯有疑議的或發現勘誤歡迎指正,[點此](https://github.com/waylau/apache-shiro-1.2.x-reference/issues)提問。
- Introduction
- 1. Introduction 介紹
- 2. Tutorial 教程
- 3. Architecture 架構
- 4. Configuration 配置
- 5. Authentication 認證
- 6. Authorization 授權
- 6.1. Permissions 權限
- 7. Realms
- 8. Session Management
- 9. Cryptography 密碼
- 10. Web
- 10.1. Configuration 配置
- 10.2. 基于路徑的 url 安全
- 10.3. Default Filters 默認過濾器
- 10.4. Session Management
- 10.5. JSP Tag Library
- 11. Caching 緩存
- 12. Concurrency & Multithreading 并發與多線程
- 13. Testing 測試
- 14. Custom Subjects 自定義 Subject
- 15. Spring Framework
- 16. Guice
- 17. CAS
- 18. Command Line Hasher
- 19. Terminology 術語
- 20. 10 Minute Tutorial 十分鐘教程
- 21. Beginner's Webapp Tutorial 初學者web應用教程
- 22. Application Security With Apache Shiro 用Shiro保護你的應用安全
- 23. CacheManager 緩存管理
- 24. Apache Shiro Cryptography Features 加密功能