作为一个新手之前一段时间开始使用的shiro,也有分享过一些shiro框架整合springmvc的内容。不过最近遇到一个问题困扰了我大半天,就是一个配置完整的shiro+springmvc项目只做了认证(doGetAuthenticationInfo)没做授权(doGetAuthorizationInfo),spring-shiro.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
<!-- 会话管理器 -->
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="1800000"/>
<property name="deleteInvalidSessions" value="true"/>
<property name="sessionValidationSchedulerEnabled" value="true" />
<property name="sessionValidationScheduler" ref="sessionValidationScheduler" />
<property name="sessionDAO" ref="sessionDAO" />
<property name="sessionIdCookieEnabled" value="true" />
<property name="sessionIdCookie" ref="sessionIdCookie" />
<property name="cacheManager" ref="cacheManager" />
</bean>
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
<property name="sessionIdGenerator" ref="sessionIdGenerator" />
<property name="activeSessionsCacheName" value="shiro-activeSessionCache" />
</bean>
<bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
<!-- 会话验证调度器 -->
<bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
<property name="interval" value="1800000" />
<property name="sessionManager" ref="sessionManager" />
</bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 设置安全管理器的安全数据源为自定义的 Realm -->
<!-- By default the servlet container sessions will be used. Uncomment this line
to use shiro's native sessions (see the JavaDoc for more): -->
<!-- <property name="sessionMode" value="native"/> -->
<property name="realm" ref="myRealm"/>
<property name="sessionManager" ref="sessionManager"/>
<property name="cacheManager" ref="cacheManager"/>
<property name="rememberMeManager" ref="rememberMeManager" />
</bean>
<!-- 配置缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:/applicationContext/ehcache-shiro.xml"/>
</bean>
<!-- rememberMe管理器 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<!-- rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)-->
<property name="cipherKey"
value="#{T(org.apache.shiro.codec.Base64).decode('3AvVhmFLUs0KTA3Kprsdag==')}"/>
<property name="cookie" ref="rememberMeCookie"/>
</bean>
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie" >
<constructor-arg value="sid" />
<property name="httpOnly" value="true" />
<property name="maxAge" value="-1" /><!--每当浏览器关闭清除-->
</bean>
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe"/>
<property name="httpOnly" value="true"/>
<property name="maxAge" value="604800"/> <!--7天 -->
</bean>
<bean id="myRealm" class="com.clear.cnemc.realm.CustomRealm">
<!-- 配置缓存相关 -->
<!-- 启用缓存 -->
<property name="cachingEnabled" value="true"/>
<!-- 开启认证缓存-->
<property name="authenticationCachingEnabled" value="true"/>
<!-- 指定认证缓存的名字(与 ehcache.xml 中声明的相同) -->
<property name="authenticationCacheName" value="authenticationCache"/>
<!--开启授权缓存-->
<property name="authorizationCachingEnabled" value="true"/>
<!-- 指定授权缓存的名字(与 ehcache.xml 中声明的相同) -->
<property name="authorizationCacheName" value="authorizationCache"/>
</bean>
<bean id="VcodeControlFilter" class="com.clear.api.web.system.VcodeControlFilter" />
<bean id="KickoutSessionControlFilter" class="com.clear.api.web.system.KickoutSessionControlFilter" >
<property name="sessionManager" ref="sessionManager"/>
<property name="cacheManager" ref="cacheManager"/>
<property name="kickoutAfter" value="false"/>
<property name="maxSession" value="1"/>
<property name="kickoutUrl" value="/login.jsp?kickout=1"/>
</bean>
<!-- Shiro生命周期处理器 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.jsp"/>
<property name="unauthorizedUrl" value="/jsp/unauthorized.jsp"/>
<property name="filterChainDefinitions">
<value>
/unauthorized.jsp = anon
/login.jsp = anon,kscf
<!-- /sys/logout = logout -->
/jsp/** = authc,kscf
/sys/verificationCode = vcode
/resources/** = anon
/jsp/home.jsp = anon
</value>
</property>
<property name="filters">
<map>
<entry key="kscf" value-ref="KickoutSessionControlFilter" />
<entry key="vcode" value-ref="VcodeControlFilter" />
<entry key="IsLoginAccessControlFilter" value-ref="IsLoginAccessControlFilter" /> -->
</map>
</property>
</bean>
</beans>
那么我的是什么问题呢? 我先百度了一下,发现全都是说要在springmvc的配置文件(注意我展示的是shiro整合springmvc的配置文件)中添加
<aop:config proxy-target-class="true"/>
但是从上面看出我并没有使用注解方式,而是直接在配置文件中绑定。所以可以直接pass,但是怎么找基本都是一个答案,这种不管什么都转载的真的很烦。不过最终还是找出了原因——是因为我的controller处理以后只返回了一个json然后就没有了,让我们结合下面的配置一起讲
<property name="filterChainDefinitions">
<value>
/unauthorized.jsp = anon
/login.jsp = anon,kscf
<!-- /sys/logout = logout -->
/jsp/** = authc,kscf
/sys/verificationCode = vcode
/resources/** = anon
/jsp/home.jsp = anon
</value>
</property>
这里是默认的过滤器,其实授权是在地址变化的时候才会进行的行为,如果之前没有授权缓存,那么每当地址跳转时,就会调用doGetAuthorizationInfo,有缓存才去缓存,然后拦截器过滤没有权限的用户。所以,我就是因为没有跳转才没执行doGetAuthorizationInfo的。
对了,一开始我加上了跳转也没好,而是新建了也realm把之前一个的内容copy过去,然后就好了。这是我的编程工具的问题,你们也可以试一下,emmmm。