Apache Shiro 10分鐘入門教程
——翻譯 崔傳新
1.簡介
歡迎來到Apache Shiro的10分鐘教程!
通過閱讀這個快速簡單的教程,您將充分了解開發人員如何在其應用程序中使用Shiro。 而且你應該可以在10分鐘內做到這一點。
2.概覽
什麼是Apache Shiro?
實際上,它實現了管理應用程序安全性的所有方面,同時儘可能避免出現問題。 它建立在完善的接口驅動設計和麵向對象的原則之上,可以在任何你想象得到的地方實現自定義行為。 但是,對於所有事情來說,默認情況下都是合理的,這與應用程序安全性是一樣的。 至少這是我們所追求的。
Apache Shiro能做什麼?
很多 。 但我們不想擴張"快速入門"的內容。 如果您想了解它可以為您做什麼,請查看我們的功能頁面。 此外,如果您對我們如何開始以及為什麼存在感到好奇,請參閱Shiro History and Mission頁面。
ok,現在我們來做一些事情吧!
說明: Shiro可以在任何環境下運行,從最簡單的命令行應用程序到最大的企業Web和集群應用程序,但是我們將在這個快速入門(QuickStart)中使用一個簡單的"main"方法來完成一個最簡單的例子,以便可以獲得對API的應用體驗。
3.下載
1)確保您安裝了JDK1.6+和Maven 3.0.3+。
2)從下載頁面下載最新的Shiro"源代碼分發"包。 在這個例子中,我們使用1.3.2發行版本。
3)解壓源代碼包
$ unzip shiro-root-1.3.2-source-release.zip
4)進入quickstart目錄
$ cd shiro-root-1.3.2/samples/quickstart
5)運行QuickStart
$ mvn compile exec:java
這個目標只會打印出一些日誌消息,讓你知道發生了什麼,然後退出——(主要Maven構建項目的過程,包括下載一些有關的組件,下載後,下次運行就不再次下載了)。 在閱讀本快速入門指南時,請隨時查看samples / quickstart / src / main / java / Quickstart.java下的代碼。 根據需要隨時更改該文件並運行上述mvn compile exec:java命令。
備註說明:
我這裡在windows8平臺下運行體驗的,環境為JDK1.8+maven3.5;步驟同上。
為了知道運行結果,我在源代碼推出前位置加了一行代碼,以觀測效果:
log.info("\n====This is Quikstart Exampel.It is done!====");//增加代碼行
結果示意圖:
4.Quickstart.java
上面引用的Quickstart.java文件包含了所有可以幫助您熟悉API的代碼。 現在讓我們把它分成大塊,這樣你就可以很容易地理解發生了什麼。
幾乎在所有環境中,您都可以通過以下調用獲取當前正在執行的用戶:
Subject currentUser = SecurityUtils.getSubject();
使用SecurityUtils.getSubject(),我們可以獲得當前正在執行的Subject。 主體只是應用程序用戶的特定安全"視圖"。 我們實際上想稱它為'User(用戶)',因為這"有道理",但我們決定不這麼幹:太多的應用程序都有現有的API,它們已經擁有自己的User類/框架,我們不想與這些API衝突。 另外,在安全領域,術語Subject實際上是公認的命名法。 ok,繼續...
獨立應用程序中的getSubject()調用,可能會根據特定於應用程序的位置中的用戶數據以及服務器環境(例如Web應用程序)返回相應Subject,並根據與當前線程或傳入請求關聯的用戶數據而獲取Subject 。
現在你有一個主題,你可以用它做什麼?
如果您想在應用程序的當前會話期間向用戶提供可用的內容,則可以獲得他們的會話:
Session session = currentUser.getSession(); session.setAttribute( "someKey", "aValue" );
Session是一個Shiro特定的實例,它給你提供了大多數習慣的常規HttpSession實例,但有一些額外的好處和一個很大的區別:它不需要HTTP環境!
如果在Web應用程序內部署,默認情況下會話將基於HttpSession。 但是,在非Web環境中,就像這個簡單的快速入門一樣,Shiro默認會自動使用它的企業會話管理。 這意味著無論部署環境如何,您都可以在應用程序中的任何層中使用相同的API。 這將打開一個全新的應用程序世界,因為任何需要會話的應用程序都不需要強制使用HttpSession或EJB Stateful Session Beans。 而且,任何客戶端技術現在都可以共享會話數據。
所以現在你可以獲得一個Subject和他們的Session。 那些真正有用的東西比如檢查是否允許他們做事情,比如檢查角色和權限?
那麼,我們只能對已知的用戶進行這些檢查。 上面的Subject實例代表當前用戶,但誰是當前用戶? 其實,他們是匿名的 - 也就是說,直到他們登錄至少一次。 所以,讓我們這樣做:
if ( !currentUser.isAuthenticated() ) {
//以gui特定方式收集用戶主體和憑證-principals and credentials
//如html表單的用戶名/密碼,X509證書,OpenID等。
//我們將在這裡使用用戶名/密碼示例,因為它是最常見的。
//(你知道這是什麼電影嗎?;)
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
//this is all you have to do to support 'remember me' (no config - built in!):
//這就是你需要做的所有事情以便來支持'記住我'(沒有配置 - 內置!)
token.setRememberMe(true);
currentUser.login(token);
}
就這樣! 應用起來不可能更容易了。
但是,如果他們的登錄嘗試失敗呢? 你可以捕捉各種具體的例外情況,告訴你到底發生了什麼,並允許你相應地處理和做出反應:
try {
currentUser.login( token );
//如果沒有例外,就是這樣,搞定!
} catch ( UnknownAccountException uae ) {
//用戶名不在系統中,如何向他們顯示錯誤消息?
} catch ( IncorrectCredentialsException ice ) {
//密碼不匹配,是否再試?
} catch ( LockedAccountException lae ) {
//該用戶名的帳戶被鎖定 - 無法登錄。如何顯示一條消息?
}
... 更多類型的異常檢查——如果你想要 ...
} catch ( AuthenticationException ae ) {
//意外情況 - 怎麼處理?
}
您可以檢查許多不同類型的例外情況,或者拋出Shiro可能無法解釋的自定義異常情況。 有關更多信息,請參閱AuthenticationException JavaDoc。
ok,到現在為止,我們有一個登錄用戶。 我們還能做什麼?
讓我們看看他們是誰:
//打印他們的標識主體(在這種情況下是用戶名)
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.");
}
另外,我們可以執行非常強大的實例級權限檢查 - 查看用戶是否有權訪問特定類型實例的功能:
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(); //刪除所有標識信息並使其會話無效。
那麼,這就是在應用程序開發人員級別使用Apache Shiro的核心。 雖然有一些非常複雜的東西在引擎蓋下進行,使得這項工作如此優雅,但這確實是它的全部。
但是你可能會問自己,"但是誰負責在登錄時獲取用戶數據(用戶名和密碼,角色和權限等),以及誰在運行時真正執行這些安全檢查?",這麼問就對了——你來做:通過實施 Shiro稱之為Realm的東西,並將該Realm插入到Shiro的配置中來完成。
但是,如何配置Realm很大程度上取決於您的運行時環境。 例如,如果運行獨立應用程序,或者如果您有基於Web的應用程序,或基於Spring或JEE容器的應用程序或其組合, 這種類型的配置不在本快速入門的範圍之內,因為它的目的是讓您對API和Shiro的概念感到滿意。
感謝您的關注。 我們希望您喜歡使用Apache Shiro!
下次分享更高層級的實戰應用案例。
閱讀更多 3T教育編程猿 的文章