Apache Shiro Web應用整合-配置
將Shiro 整合到任何 Web 應用程式的最簡單的方法是在 web.xml 中配置 ContextListener 和 Filter ,來使 Shiro 知道如何讀取 Shiro 的 INI 配置檔案。
注意:Spring 框架使用者將不執行此設定。如果你使用 Spring ,你將要閱讀關於 Spring 特定的 Web 配置。
Web.xml
Shiro 1.2 and later
在Shiro 1.2 及以後版本,標準的 Web 應用程式通過新增下面的 XML 塊到 web.xml 來初始化 Shiro :
<listener> <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class> </listener> … <filter> <filter-name>ShiroFilter</filter-name> <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class> </filter> <filter-mapping> <filter-name>ShiroFilter</filter-name> <url-pattern>*/</url-pattern> </filter-mapping> |
這是假設Shiro INI 配置檔案在以下兩個位置任意一個,並使用最先發現的那個:
1. /WEB-INF/shiro.ini
2. 在 classpath 根目錄下 shiro.ini 檔案
下面是上述配置所做的事情:
l
EnvironmentLoaderListener 初始化一個
Shiro WebEnvironment
例項(其中包含
Shiro
需要的一切操作,包括
SecurityManager
),使得它在
ServletContext
中能夠被訪問。如果你需要在任何時候獲得
WebEnvironment
l ShiroFilter 將使用此 WebEnvironment 對任何過濾的請求執行所有必要的安全操作。
l 最後,filter-mapping 的定義確保了所有的請求被 ShiroFilter 過濾,建議大多數 Web 應用程式使用以確保任何請求是安全的。
預設情況下,EnvironmentLoaderListener 將建立一個 IniWebEnvironment 例項,讀取 Shiro 基於 INI 檔案的配置。如果你願意,你可以在 web.xml 中指定一個自定義的 ServletContext context-param :
<context-param> <param-name>shiroEnvironmentClass</param-name> <param-value>com.foo.bar.shiro.MyWebEnvironment</param-value> </context-param> |
IniWebEnvironment 將會去讀取和載入 INI 配置檔案。預設情況下,這個類會自動地在下面兩個位置尋找 Shiro.ini 配置(按順序)。
1. /WEB-INF/shiro.ini
2. classpath:shiro.ini
它將使用最先發現的那個。
然而,如果你想把你的配置放在另一位置,你可以在web.xml 中用 contex-param 指定該位置。
<context-param> <param-name>shiroConfigLocations</param-name> <param-value>YOUR_RESOURCE_LOCATION_HERE</param-value> </context-param> |
預設情況下,在ServletContext.getResource 方法定義的規則下, param-value 是可以被解析的。例如, /WEB-INF/some/path/shiro.ini 。
但你也可以指定具體的檔案系統,如classpath 或 URL 位置,通過使用 Shiro 支援的合適的資源字首,例如:
l file://home/foobar/myapp/shiro.ini
l classpath:com/foo/bar/shiro.ini
Shiro 1.1 and earlier
在Web 應用程式中使用 Shiro 1.1 或更早版本的最簡單的方法是定義 IniShiroFilter 並指定一個 filter-mapping:
<filter> <filter-name>ShiroFilter</filter-name> <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class> </filter> … <!-- Make sure any request you want accessible to Shiro is filtered. /* catches all --> <!-- requests. Usually this filter mapping is defined first (before all others) to --> <!-- ensure that Shiro works in subsequent filters in the filter chain: --> <filter-mapping> <filter-name>ShiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
如果你不想將你的INI 配置放在 /WEB-INF/shiro.ini 或 classpath:shiro.ini ,你可以指定一個自定義的資源位置。新增一個 configPath 的 init-param ,並指定資源位置。
<filter> <filter-name>ShiroFilter</filter-name> <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class> <init-param> <param-name>configPath</param-name> <param-value>/WEB-INF/anotherFile.ini</param-value> <init-param> </filter> |
最後,也可以將你的INI 配置嵌入到 web.xml 中而不使用一個獨立的 INI 檔案。你可以通過使用 init-param 做到這點,而不是 configPath :
<filter> <filter-name>ShiroFilter</filter-name> <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class> <init-param> <param-name>config</param-name> <param-value> # INI Config Here </param-value> </init-param> </filter> ... |
內嵌配置對於小型的或簡單的應用程式通常是很好用的,但是由於以下原因一般把它具體化到一個專用的Shiro.ini 檔案中:
l 你可能編輯了許多安全配置,不希望為web.xml 新增版本控制。
l 你可能想從餘下的web.xml 配置中分離安全配置。
l 你的安全配置可能變得很大,你想保持web.xml 的苗條並易於閱讀。
l 你有個負責的編譯系統,相同的shiro 配置可能需要在多個地方被引用。
Web INI配置
除了在配置章節描述的標準的[main] , [user] 和 [roles] 項外,你可以在 shiro.ini 檔案中指定具有 web 特性的 [urls] 項:
[urls]項允許你做一些在我們已經見過的任何 Web 框架都不存在的東西:在你的應用程式中定義自適應過濾器鏈來匹配 URL 路徑!
在urls 項的每一行格式如下:
URL_Ant_Path_Expression = Path_Specific_Filter_Chain
例如:
… [urls] /index.html = anon /user/create = anon /user/** = authc /admin/** = authc, roles[administrator] /rest/** = authc, rest /remoting/rpc/** = authc, perms["remot:invoke"] |
等號左邊是一個與Web 應用程式上下文根目錄相關的 Ant 風格的路徑表示式。請注意,所有的路徑表示式都是相對於你的應用程式的上下文根目錄而言的。所有的路徑都是相對於 HttpServletRequest.getContextPath() 的值來的。
順序的重要性! URL 路徑表示式按事先定義好的順序判斷傳入的請求,並遵循 FIRST MATCHWINS 這一原則。例如,讓我們假設有如下鏈的定義: /account/** = ssl, authc /account/signup = anon 如果傳入的請求旨在訪問/account/signup/index.html (所有 'anon'ymous 使用者都能訪問),那麼它將永不會被處理!原因是因為 /account/** 的模式第一個匹配了傳入的請求,“短路”了其餘的定義。 始終記住基於FIRST MATCH WINS 的原則定義你的過濾器鏈! |
等號右邊是逗號隔開的過濾器列表,用來執行匹配該路徑的請求。它必須符合以下格式:
filter1[optional_config1], filter2[optional_config2], ..., filterN[optional_configN]
l filterN 是一個定義在 [main] 項中的 filter bean 的名字。
l [optional_configN]是一個可選的括號內的對特定的路徑,特定的過濾器有特定含義的字串(每個過濾器,每個路徑的具體配置!)。若果該過濾器對該 URL 路徑並不需要特定的配置,你可以忽略括號,於是 filteNr[] 就變成了 filterN 。
因為過濾器標誌符定義了鏈(又名列表),所以請記住 順序問題 !請按順序定義好你的逗號分隔的列表,這樣請求就能夠流通這個鏈。
在過濾器鏈中能夠使用的過濾器“池”被定義在[main] 項。在 [main] 項中指派給它們的名字就是在過濾器鏈定義中使用的名字。例如:
[main] … myFilter = com.company.web.some.FilterImplementation myFilter.property1 = value1 … [urls] … /some/path/** = myFilter |