前陣子在先後端分離項目中集成shiro項目,折騰了一會兒,參考了網上一些博客,發現大多都仍是以前傳統的模式,並不適用於先後端分離結構。今天抽空整理了下demo,方便之後使用以及後來人參考。web
關於shior框架的介紹能夠參考這篇,須要引入相關jar以下:redis
<!--shiro核心jar from 官網 www.1b23.com--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <!--實現session共享。緩存等--> <dependency> <groupId>org.crazycake</groupId> <artifactId>shiro-redis</artifactId> <version>3.2.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
未整合Spring/SpringBoot之前,是須要在Web.xml
中定義org.apache.shiro.web.servlet.ShiroFilter過濾器的
Shiro的初始化工做在web.xml中設置監聽器完成spring
<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 的 EnvironmentLoaderListener 就是一個典型的 ServletContextListener,它也是整個 Shiro Web 應用的入口 。
EventListener 是一個標誌接口,裏面沒有任何的方法,Servlet 容器中全部的 Listener 都要繼承這個接口(這是 Servlet 規範)。apache
ServletContextListener 是一個 ServletContext 的監聽器,用於監聽容器的啓動與關閉事件,包括以下兩個方法:
void contextInitialized(ServletContextEvent sce); // 當容器啓動時調用
void contextDestroyed(ServletContextEvent sce); // 當容器關閉時調用後端
能夠從 ServletContextEvent 中直接獲取 ServletContext 對象。跨域
EnvironmentLoaderListener 不只實現了 ServletContextListener 接口,也擴展了 EnvironmentLoader 類,應該是須要在 Servlet 容器中調用 EnvironmentLoader 對象的生命週期方法
從 Shiro 1.2 開始引入了 Environment/WebEnvironment 的概念,即由它們的實現提供相應的 SecurityManager 及其相應的依賴。ShiroFilter 會自動找到 Environment 而後獲取相應的依賴。
經過 EnvironmentLoaderListener 來建立相應的 WebEnvironment,並自動綁定到 ServletContext,默認使用 IniWebEnvironment 實現。緩存
EnvironmentLoader的功能:安全
當容器啓動時,讀取 web.xml 文件,從中獲取 WebEnvironment 接口的實現類(默認是 IniWebEnvironment),初始化該實例,並將其加載到 ServletContext 中。
當容器關閉時,銷燬 WebEnvironment 實例,並從 ServletContext 將其移除。
IniWebEnvironment的功能:springboot
查找並加載 shiro.ini 配置文件,首先從自身成員變量裏查找,而後從 web.xml 中查找,而後從 /WEB-INF 下查找,而後從 classpath 下查找,若均未找到,則直接報錯。
當找到了 ini 配置文件後就開始解析,此時構造了一個 Bean 容器(至關於一個輕量級的 IOC 容器),最終的目標是爲了建立 WebSecurityManager 對象與 FilterChainResolver 對象,建立過程使用了 Abstract Factory 模式
EnvironmentLoaderListener無非就是在容器啓動時建立 WebEnvironment 對象,並由該對象來讀取 Shiro 配置文件,建立WebSecurityManager(安全管理器)與 FilterChainResolver(過濾鏈解析器) 對象,在ShiroFilter中起到了重要做用。session
ShiroFilter 是整個 Shiro 的入口點,用於攔截須要安全控制的請求進行處理。
由於它攔截了全部的請求,後面的 Authentication(認證)和Authorization(受權)都由ShiroFilter說了算
和Spring/SpringBoot整合之後,咱們只須要注入ShiroFilter便可,ShiroFilter由ShiroFilterFactoryBean負責建立。因此注入ShiroFilterFactoryBean,由 ShiroFilterFactoryBean建立 ShiroFilter便可
服務端需開啓跨域支持
只返回Json,不要重定向
OPTIONS Request 不進行鑑權操做