- 一步一步教你用shiro——1引入shiro框架
- 一步一步教你用shiro——2配置并自定義realm
- 一步一步教你用shiro——3配置并自定義sessionManager
- 一步一步教你用shiro——4配置并自定義sessionDao
- 一步一步教你用shiro——5配置rememberMe
- 一步一步教你用shiro——6總結(jié)和心得
shiro這個(gè)權(quán)限框架確實(shí)很實(shí)用很方便,網(wǎng)上關(guān)于它的分析也很多犀勒,但是有很多資料都太老了。尚硅谷的視頻教程中關(guān)于session管理的部分有錯(cuò)誤。《一頭扎進(jìn)shiro》是老版本shiro而且太淺了(硬是說session用web容器的就夠了饭玲,沒必要改伊履,敢情你家應(yīng)用都是單實(shí)例的?)艺骂,慕課網(wǎng)的視頻最全面,但是不夠細(xì)隆夯。有很多問題只能自己看源碼钳恕,做嘗試解決别伏。
所以將shiro的一些經(jīng)驗(yàn)記錄下來,希望能幫助到讀到本文的你忧额,本文環(huán)境shiro1.3.2厘肮、spring4.3.5沒有使用boot、jdk8睦番、tomcat8.5类茂、mysql5.6、redis3.2.11
目標(biāo):通過shiro實(shí)現(xiàn)對(duì)后端接口進(jìn)行權(quán)限控制托嚣,所有靜態(tài)資源都不需要權(quán)限驗(yàn)證巩检,使用redis實(shí)現(xiàn)session共享,避免session單點(diǎn)問題
- shiro1.4.0在17年5月份就有了示启,但是現(xiàn)在shiro官網(wǎng)上還是說1.3.2是最后的穩(wěn)定版兢哭,為了保險(xiǎn),還是用這個(gè)老版本
- shiro不推薦使用shiro-all這個(gè)總包夫嗓,可能會(huì)造成maven工作不正常迟螺,一般常用的是core、spring舍咖、web這三個(gè)包
<!--工程中單獨(dú)引入了slf4j矩父,不去除的話jar包沖突-->
<!--可以使用該命令查看jar包是否有沖突,mvn dependency:tree -Dverbose|grep conflict-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
- web.xml中增加spring的代理filter谎仲,實(shí)際filter是shiro的ShiroFilterFactoryBean(后面說ShiroFilterFactoryBean的具體配置)浙垫,targetFilterLifecycle為true代表由spring控制該filter的生命周期。
- 一般這段配置不需要改郑诺,只需要改url-pattern夹姥。shiro源碼中的sample配的是/*,因?yàn)槲抑幌肟刂朴脩粼L問后端接口的權(quán)限辙诞,靜態(tài)資源可以隨便訪問辙售,所以后端接口都用的api開頭,讓shiro過濾器只對(duì)api開頭的請(qǐng)求生效(這樣還可以避免頻繁訪問session飞涂,造成redis壓力過大的問題旦部,具體后面說)
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/api/*</url-pattern>
</filter-mapping>
- 在spring的配置文件中配置ShiroFilterFactoryBean,注意id一定要和web.xml中 的filter-name一致较店,否則proxyFilter找不到實(shí)際filter士八。
- shiro的內(nèi)置過濾器可以百度每個(gè)的含義和配制方法,這里需要說下authc梁呈。使用authc的接口是一定要輸入用戶名密碼登陸后才能訪問婚度,哪怕通過shiro的rememberMe自動(dòng)登錄的用戶也需要重新輸入用戶名密碼重新登錄后才能訪問。
- 就像我們平時(shí)訪問淘寶官卡,一進(jìn)網(wǎng)站就自動(dòng)登錄了蝗茁,但是第一次做敏感操作的時(shí)候還是要輸入用戶名密碼登陸進(jìn)行一次認(rèn)證醋虏,然后再做敏感操作都不需要輸入用戶名密碼了。
<!--配置全局權(quán)限過濾器-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--shiro最核心組件哮翘,具體后面說-->
<property name="securityManager" ref="securityManager"/>
<!--設(shè)置沒有登錄時(shí)的跳轉(zhuǎn)地址-->
<property name="loginUrl" value="/static/html/login.html"/>
<!--設(shè)置權(quán)限不足時(shí)的跳轉(zhuǎn)地址-->
<property name="unauthorizedUrl" value="/static/html/noPerm.html"/>
<!--對(duì)哪個(gè)后端接口使用哪個(gè)過濾器進(jìn)行配置颈嚼,等號(hào)后邊是shiro內(nèi)置過濾器的名字-->
<property name="filterChainDefinitions">
<value>
<!--匿名訪問,/api/login是登陸接口饭寺,當(dāng)然可以隨便訪問-->
/api/login = anon
/api/test? = authc
<!--本工程中上傳文件的接口阻课,只允許有common角色的用戶訪問-->
/api/file = roles[common]
<!--用戶退出登錄的接口,后端不需要實(shí)現(xiàn)該接口佩研,logout攔截到/api/logout的url后柑肴,就自動(dòng)清除登錄狀態(tài)回到首頁了-->
<!--因?yàn)樵趙eb.xml中設(shè)置的url-parttern是/api/*,隨意只有api開頭的url才會(huì)被攔截-->
/api/logout = logout
<!--使用自定義攔截器的接口-->
<!--/api/selfFilter = myFilter-->
<!--其他所有接口都需要認(rèn)證旬薯,也就是需要之前輸入過賬號(hào)密碼登錄過-->
/** = authc
</value>
</property>
<!--加入自定義filter,在filterChainDefinitions可以通過key來引用-->
<!--<property name="filters">-->
<!--<map>-->
<!--<entry key="myFilter">-->
<!--<bean class="MyFilter"/>-->
<!--</entry>-->
<!--</map>-->
<!--</property>-->
</bean>