使用shiro保護你的springboot應用

wj596發表於2018-01-06

專案簡介

 

springboot中使用shiro大都是通過shiro-spring.jar進行的整合的,雖然不是太複雜,但是也無法做到spring-boot-starter風格的開箱即用。
專案中經常用到的功能比如:驗證碼、密碼錯誤次數限制、賬號唯一使用者登陸、動態URL過濾規則、無狀態鑑權等等,shiro還沒有直接提供支援。
jsets-shiro-spring-boot-starter對這些常用的功能進行了封裝和自動匯入,少量的配置就可以應用在專案中。
1、專案地址:jsets-shiro-spring-boot-starter
2、使用說明:使用說明
3、示例應用:jsets-shiro-demo
如果您對這個元件感興趣請star收藏,在使用這個元件中有任何問題或意見都可以在這裡交流,歡迎提交程式碼。

已完成功能

1、spring-boot-starter風格的開箱即用。
2、區分ajax請求和普通請求,普通請求通過跳轉來響應未登陸和未授權,AJAX請求通過狀態碼和訊息響應未登陸和未授權。
3、整合jcaptcha驗證碼。
4、密碼輸入錯誤,重試次數限制。
5、賬號唯一使用者登陸,一個賬號只允許一個使用者登陸。
6、redis快取(單機、分散式)支援,認證\授權資料快取同步。
7、動態URL過濾規則。
8、無狀態認證授權支援,共存有狀態和無狀態兩種鑑權方式,無狀態鑑權支援JWT(JSON WEB TOKEN)、HMAC(雜湊訊息認證碼)兩種協議。
9、線上session管理,強制使用者下線功能。

後續計劃功能

1、cas單點登陸整合
2、oauth2.0支援

 

快速體驗

1、pom.xml中新增:

<dependency>
    <groupId>org.jsets</groupId>
    <artifactId>jsets-shiro-spring-boot-starter</artifactId>
    <version>0.0.1</version>
</dependency>

2、application.properties新增下面配置:

###jsets-shiro配置
#登陸頁面
jsets.shiro.login-url=/login
#登陸成功頁面
jsets.shiro.login-success-url=/index
#忽略攔截的URL,靜態資源
jsets.shiro.filte-rules[0]=/assets/**-->anon
#登陸
jsets.shiro.filte-rules[1]=/login/**-->authc
#退出
jsets.shiro.filte-rules[2]=/logout/**-->logout
#所有路徑,斷言session中存在使用者
jsets.shiro.filte-rules[3]=/**-->user

3、建立Controller類IndexAction.java:

@Controller
public class IndexAction {
    @RequestMapping("/")
    public String def() {
         return "index";
    }
    @RequestMapping("/index")
    public String index() {
         return "index";
    }
    @RequestMapping("/login")
    public String login() {
        return "login";
    }
}

4、建立登陸頁面login.html:

<form class="login-form" action="${ctx}/login" method="post">
    <div class="form-item">
    使用者名稱:<input type="text" name="username" />
    </div>
    <div class="form-item">
        密碼:<input type="password" name="password" />
    </div>
    <div class="form-item">
        <button type="submit">登入</button>
    </div>
</form>
<!-- 認證資訊 -->
<font color="red">${Request["shiro_auth_message"]!}</font>

5、建立主頁index.html:

<div class="body">
歡迎您:${Session.shiro_current_user.account!}
<br>
退出:<a href="${ctx}/logout">退了</a>
</div>

6、啟用jsets-shiro-spring-boot-starter:

@SpringBootApplication
@EnableJsetsShiro
public class Application{
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

啟動springboot應用,控制檯會列印出元件預置的體驗賬號和密碼:


 

使用這個賬號和密碼就可以登陸系統了。

 

鑑權要素

鑑:認證(Authentication)即證明您是賬號表示的那個人,基於form的認證中使用口令(密碼),rest api認證中使用令牌(token)。
權:許可權驗證(Authorization)即根據一個判斷規則來驗證您是否能執行一個操作。

認證的過程需要賬號資料,這個資料至少包含三個元素:賬號(使用者名稱)、密碼、賬號是否可用。
jsets-shiro-spring-boot-starter中使用Account介面表示賬號資料、使用ShiroAccountProvider介面為鑑權操作提供Account資料,資料來源不限比如可以從資料庫、檔案、LDAP、遠端服務等各種方式載入。

許可權驗證的過程需要許可權資料和規則資料,許可權泛指能否操作資源,角色是許可權的集合,如果使用許可權來表示一個使用者能操作的資源顯然不方便,所以大部分系統的安全模型都是基於RBAC(Role-Based Access Control 基於角色的許可權訪問控制)的。jsets-shiro-spring-boot-starter同樣使用ShiroAccountProvider介面為鑑權操作提供許可權(角色)資料,資料來源不限。

具體參見"使用說明--接入使用者資料"一章。

規則資料,如果沒有規則就不存在判斷,許可權驗證也就無從談起,在shiro中規則表示成這樣:

article/update=roles[role_editor]
article/delete=roles[role_chief]
article/publish=roles[role_chief]

"article/update"就是操作的資源,"roles[role_editor]"是判斷標準,表示使用者的角色列表中包含"role_editor"角色,操作加上判斷標準就是規則。jsets-shiro-spring-boot-starter中您可以在application.properties中配置這樣的規則。也可以通過shiro的AOP方式配置規則,類似於這樣:

@RequiresRoles("role_editor")
public void update(Article article){
}

這兩種方式是有侷限的,比如角色-資源的對應關係發生變更,比如新增了一種角色,那就只能修改配置或者程式碼然後重啟動系統才能使得這些變更生效。實際開發中則更希望通資料庫查詢出角色-資源的對應資料,動態生成URL規則,當角色-資源的對應關係發生變更時能重新整理並立即使用者這些規則。

您可以通過ShiroFilteRulesProvider介面為鑑權操作提供規則資料,並且支援實時重新整理應用這些規則。

具體參見"使用說明--動態URL過濾"一章。

 

無狀態鑑權

無狀態(Stateless)鑑權通常應用在微服務(REST API)架構中,使用數字摘要(簽名)技術生成一個token作為認證和授權的憑證,整個認證和授權過程不依賴於cookie或session,服務端不保留客戶端狀態因此每次請求都要攜帶這個token。

jsets-shiro-spring-boot-starter提供兩種無狀態鑑權方式,分別是雜湊訊息認證碼(HMAC)、JSON WEB TOKEN(JWT)。

HMAC適合端到端的鑑權,即客戶端拿著簽名讓服務端進行驗籤。
JWT適合客戶端詢問系統B是否有權訪問系統C和系統N如果有請開份憑證,然後拿著憑證讓系統C和系統N進行驗籤。

JWT是自包含的,令牌中攜帶訪問主張(角色或許可權),所以JWT鑑權不需要查詢資料。HMAC鑑權則需要查詢資料庫獲取角色或許可權資料。HMAC和JWT鑑權過程均不產生session。

如果您的系統即有狀態鑑權(即基於FORM的登陸認證)又有無狀態鑑權(即提供rest介面),畢竟不是所有的系統都做了服務化拆分的,預設情況下HMAC也是使用ShiroAccountProvider介面為鑑權操作提供身份認證和許可權驗證資料,和有狀態鑑權公用一套資料。如您想拆分它們,即HMAC使用自己的鑑權資料,可以使用ShiroStatelessAccountProvider為無狀態鑑權提供資料。

具體參見"使用說明--無狀態鑑權"一章。

 

元件擴充套件

JsetsShiroConfigurationAdapter是shiro配置的介面卡,通過它您可以定製Realm、filter、SessionDAO、CacheManager等。

 

示例展示

jsets-shiro-demo是jsets-shiro-spring-boot-starter是應用示例,做的不是很精細,主要為了演示功能實現。

主介面:


 

驗證碼:


 

 

使用者被踢出:

 

密碼輸入錯誤重試次數限制:


 

角色列表:


 

許可權攔截:

 

資源分配:

 

許可權驗證通過:

 

HMAC驗籤通過:


 

HMAC簽名失效:


 

HMAC簽名無效:


 

JWT許可權驗證失敗:


 

JWT需要身份認證:


 

線上使用者列表:


 

強制使用者下線:


 

更多功能和特性請參見jsets-shiro-spring-boot-starter原始碼和使用說明。

相關文章