一、介紹
看完這個10分鍾入門之后,你就知道如何在你的應用程序中引入和使用Shiro。以后你再在自己的應用程序中使用Shiro,也應該可以在10分鍾內搞定。
二、概述
關於Shiro的廢話就不多說了,詳情可以看本系列第一篇博文:Apache Shiro系列一:初識
答案是很多,但是在這里我們就不展開說了,如果對這個有興趣,可以去看Shiro的特性。
三、下載
1) 確保安裝了1.6及其以上版本的JDK,以及3.0.3以上版本的maven;
2) 從Download 頁面下載最新版本的”Source Code Distribution”,我們下面的例子將使用1.3.2版本;
3) 解壓;
4) 進入到quickstart目錄;
$ cd shiro-root-1.3.2/samples/quickstart
5) 運行quickstart;
$ mvn compile exec:java
在看本入門文檔的過程中,可以打開源文件samples/quickstart/src/main/java/Quickstart.java,並且隨意修改以測試你的想法。
四、QuickStart.java
下面我們來分解說明Quickstart.java內的源碼以便你可以更好的理解。
在任何環境下你都可以通過如下代碼來獲取當前登錄的用戶。
Subject currentUser =SecurityUtils.getSubject();
所謂Subject其實就是其他系統中的User,這里只是換一個說法,因為能夠登錄系統的不僅僅是人,還有其他系統。
如果是在一個獨立的應用程序中調用getSubject(),我們會得到一個應用程序本地登錄的用戶信息,如果是一個web應用,則會得到一個和當前線程或者當前的session相關的用戶。
不管怎么樣,現在你得到了一個用戶了,接下來可以做什么呢?
如果你想要讓某些數據在當前用戶登錄會話期間內一直有效,則可以像下面這么做:
Session session = currentUser.getSession();
session.setAttribute("someKey","aValue");
我們可以把這個Session當成是HttpSession在Shiro中的特殊實現,他和HttpSession有着相似的接口,大家用起來不會陌生。但是他還有一個額外的好處:不依賴於HTTP的上下文環境。這樣你就可以在一個非web應用(比如類似於本例子的命令行程序)中使用Session了。
如果是在一個Web應用程序中使用Session,則返回的Session是一種基於HttpSession的實現;而如果是在一個非web環境下使用,則默認使用的是Enterprise Session。不管怎么樣,這意味着我們不用理會應用程序的部署環境,總是使用相同的API來操作session,帶來一致的用戶體驗。現在,web應用和非web應用可以共享session數據了。
到目前為止,我們得到了一個Subject以及他的Session,現在我們用它們來做點有實際意義的事情怎么樣,比如檢查一下這個用戶是否有權限做某件事情?
我們可以為一個已知的用戶做這些檢查。我們上文中的Subject代表着當前用戶,但是截至目前來說,誰是當前用戶呢?在真正登錄之前,Subject表示的是一個匿名用戶。下面讓我們來看看登錄怎么做。
if(!currentUser.isAuthenticated()){ //collect user principals and credentials in a gui specific manner //such as username/password html form, X509 certificate, OpenID, etc. //We'll use the username/password example here since it is the most common. //(do you know what movie this is from? ;) UsernamePasswordToken token =newUsernamePasswordToken("lonestarr","vespa"); //this is all you have to do to support 'remember me' (no config - built in!): token.setRememberMe(true); currentUser.login(token); }
就這樣,簡單的不能再簡單了。
1 try{ 2 currentUser.login( token ); 3 //if no exception, that's it, we're done! 4 }catch(UnknownAccountException uae ){ 5 //username wasn't in the system, show them an error message? 6 }catch(IncorrectCredentialsException ice ){ 7 //password didn't match, try again? 8 }catch(LockedAccountException lae ){ 9 //account for that username is locked - can't login. Show them a message? 10 } 11 ... more types exceptions to check if you want ... 12 }catch(AuthenticationException ae ){ 13 //unexpected condition - error? 14 }
//print their identifying principal (in this case, a 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."); }
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();//removes all identifying information and invalidates their session too.