Shiro-初體驗

atd681發表於2018-08-04

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, 可以正常訪問. 訪問其他頁面會跳轉至登入.