10 分鍾快速上手 Shiro 新手教程


當前用戶

現在我們能夠開始做一些我們真正關心的事情——執行安全操作。

當保護我們的應用程序時,我們對自己可能提出的最為相關的問題是“當前用戶是誰”或“當前用戶是否被允許做XXX”。

當我們編寫代碼或設計用戶接口時,問這些問題是很常見的:應用程序通常是基於用戶的背景情況建立的,且你想基於每個用戶標准體現(保障)功能。因此,對於我們考慮應用程序安全的最自然的方式是基於當前用戶。

Shiro的API使用它的Subject概念從根本上代表了“當前用戶”的概念。

幾乎在所有的環境中,你可以通過下面的調用獲取當前正在執行的用戶:

Subject currentUser = SecurityUtils.getSubject();

使用 SecurityUtils.getSubject(),我們可以獲得當前正在執行的Subject。Subject是一個安全術語,它基本上的意思是“當前正在執行的用戶的特定的安全視圖”。它並沒有被稱為"User"是因為"User"一詞通常和人類相關聯。

在安全界,術語"Subject"可以表示為人類,而且可是第三方進程,cron job,daemonaccount,或其他類似的東西。它僅僅意味着“該事物目前正與軟件交互”。

對於大多數的意圖和目的,你可以把 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() ) {
    //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 = 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 );
    //if no exception, that's it, we're done!
} catch ( UnknownAccountException uae ) {
    //username wasn't in the system, show them an error message?
} catch ( IncorrectCredentialsException ice ) {
    //password didn't match, try again?
} catch ( LockedAccountException lae ) {
    //account for that username is locked - can't login.  Show them a message?
}
    ... more types exceptions to check if you want ...
} catch ( AuthenticationException ae ) {
    //unexpected condition - error?
}

你能夠檢查到許多不同類型的異常,或拋出你自己的自定義條件的異常——Shiro 可能不提供的。請參見AuthenticationException JavaDoc 獲取更多。

Handy Hint

最安全的做法是給普通的登錄失敗消息給用戶,因為你當然不想幫助試圖闖入你系統的攻擊者。

好了,到現在為止,我們已經有了一個登錄用戶。我們還能做些什么?

比方說,他們是是誰:

//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.

總結

希望此次推出的教程幫助您了解如何在一個基本的應用程序設置 Shiro 以及 Shiro 的主要設計理念。

關注公眾號Java技術棧回復"面試"獲取我整理的2020最全面試題及答案。

推薦去我的博客閱讀更多:

1.Java JVM、集合、多線程、新特性系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、后端、架構、阿里巴巴等大廠最新面試題

覺得不錯,別忘了點贊+轉發哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM