0) 前言
Shiro: 一個易上手,設計靈活的許可權框架, 通過簡單的配置就能實現系統的安全管理.
從系統的安全形度考慮, 你的系統至少需要實現如下功能:
- 未登入的使用者訪問頁面A時跳轉至登入頁面
- 使用者登入成功後會自動跳轉至頁面A或指定頁面
- 已經登入的使用者可以直接訪問頁面B
- 普通會員不可以訪問頁面C
- 超級會員可以訪問頁面D
上述功能總結起來為兩點:
- 所訪問頁面是否需要登入
- 是否有許可權訪問頁面(許可權是需要登入之後根據登入使用者得到的)
Shiro給登入和許可權定義了兩個專有名詞, 分別是認證(authc)和授權(authz).
A,B,C三個頁面需要登入使用者訪問, 其中: C頁面需要有許可權的使用者才能訪問. 在Shiro中可以說成只有認證使用者才能訪問A,B,C頁面. 只有通過授權的使用者才能訪問頁面C
系統的安全需求已經清晰了, 下面我們來配置Shiro, 本例中程式碼只進行基礎配置, 深入內容後續講到.
由於Spring已經一統天下, 本例中的Shiro全部基於Spring進行配置.
1) 引入Shiro相關依賴
Spring下的Shiro需要三個類庫:
- shiro-web.jar: 提供filter, session相關的類
- shiro-core.jar: 核心包
- shiro-spring.jar: spring整合必備
"org.apache.shiro:shiro-core:1.3.2",
"org.apache.shiro:shiro-web:1.3.2",
"org.apache.shiro:shiro-spring:1.3.2"
複製程式碼
2) Shiro配置檔案
我們進行如下配置: 除/page/n外, 所有請求都需要認證(登入)才可以訪問.
beans {
// Shiro核心配置
shiroFilter(ShiroFilterFactoryBean) {
securityManager = ref("securityManager")
// 配置URL規則
// 有請求訪問時Shiro會根據此規則找到對應的過濾器處理
filterChainDefinitionMap = [
"/page/n" : "anon", // /page/n不需要登入即可訪問
"/**": "authc" // 其餘所有頁面需要認證(authc為認證過濾器)
]
}
// 安全管理器
securityManager(DefaultWebSecurityManager)
}
複製程式碼
shiroFilter: 定義及配置shiro核心過濾器並交由Spring管理, 需要被Shiro管理的URL在訪問時都經過該過濾器處理(下面會在web.xml
進行配置), Shiro是基於過濾器實現的安全框架, 原理是URL與過濾器對應, 當訪問URL時找到對應的過濾器, 在過濾器中處理認證和授權. Shiro內建了很多的過濾器, 下面介紹幾個常用的過濾器:
-
anon: 匿名過濾器, 不進行任何認證和授權的處理, 所有不需要認證和授權(所有人都可以訪問的頁面)配置該過濾器, 例如: CSS, JS, 圖片, 網站首頁等. 對應類為
org.apache.shiro.web.filter.authc.AnonymousFilter
-
authc: 表單認證過濾器, Shiro認證最核心的過濾器, 處理認證, 登入等操作, 所有需要認證才能訪問的URL都需配置該過濾器, 後續篇幅會根據原始碼講解該過濾器的實現原理及機制. 對應類為
org.apache.shiro.web.filter.authc.FormAuthenticationFilter
-
logout: 登出過濾器, 一般登出的URL需要配置為logout, 當使用者點選登出連結時進入該過濾器. 系統的登出操作交由Shiro處理. 對應類為
org.apache.shiro.web.filter.authc.LogoutFilter
為方便記憶與配置,上述的過濾器都是簡寫, 在Shiro中有一個簡寫和實際過濾器類的對應關係, 具體其他過濾器的簡寫可以在程式碼中進行檢視. 在org.apache.shiro.web.filter.mgt.DefaultFilter
中
anon(AnonymousFilter.class),
authc(FormAuthenticationFilter.class),
authcBasic(BasicHttpAuthenticationFilter.class),
logout(LogoutFilter.class),
noSessionCreation(NoSessionCreationFilter.class),
perms(PermissionsAuthorizationFilter.class),
port(PortFilter.class),
rest(HttpMethodPermissionFilter.class),
roles(RolesAuthorizationFilter.class),
ssl(SslFilter.class),
user(UserFilter.class);
複製程式碼
shiroFilter還可以配置:
loginUrl
: 登入頁面請求地址, 預設為/login.jsp, 當訪問請求的使用者未登入時Shiro會重定向到該地址讓使用者進行登入.successUrl
: 使用者直接訪問登入頁, 登入成功後跳轉至此地址. 使用者訪問頁面A時跳轉至登入, 登入成功後會重定向至頁面A.unauthorizedUrl
: 未授權頁面地址, 未授權的使用者頁面時, Shiro會重定向到該頁面提示使用者無訪問許可權.securityManager
: Shiro安全管理器, 提供Shiro核心的安全管理邏輯, 後續篇幅細講. 此處預設宣告一下即可.
3) Web.xml新增Shiro過濾器
上面提到了所有的URL都交由Shiro的過濾器進行處理, 因此需要在web.xml中新增shiro的過濾器
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
複製程式碼
<filter-class>
是Spring提供的代理類, 後續會講到, <filter-name>
一定要和Shiro配置檔案中的名稱相同才能找到對應的過濾器
4) Shiro配置檔案
<!-- Spring Context Listener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<!-- groovy DSL -->
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.GroovyWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- Shiro configuration -->
<param-value>classpath*:/spring-shiro.groovy</param-value>
</context-param>
複製程式碼
5) 示例程式碼
本例程式碼使用了Spring4新增的Groovy DSL
語法. 此處只是增加了Shiro配置檔案. 無其他特殊配置
至此, 一個基於Shiro控制專案認證的示例配置完成, Shiro全部採用配置. 執行專案, 訪問/page/n
, 可以正常訪問. 訪問其他頁面會跳轉至登入.
-
示例程式碼地址: github.com/atd681/alld…
-
示例程式碼專案: atd681-shiro-first