shiro
shiro是apache开源的安全框架,可方便用来处理用户信息认证、用户授权控制、信息加密等功能。
springmvc整合shiro步骤:
- servlet容器提供访问的入口(web.xml):DelegatingFilterProxy
<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>/*</url-pattern>
</filter-mapping>
工作原理:web.xml中配置DelegatingFilterProxy的Servlet对象,其代理的目标Serlvet其实是org.apache.shiro.spring.web.ShiroFilterFactoryBean,为了建立两个DelegatingFilterProxy和ShiroFilterFactoryBean关系,主要是通过Filter名称进行绑定的,当客户端发送请求时,DelegatingFilterProxy进行拦截,然后根据获取Filter名称,最后调用IOC容器的getBean的方法获取和Filter名称匹配的Bean,因ShiroFilterFactoryBean是FactoryBean因实际上处理客户端请求的是shiro在IOC容器Filter的实现类
- 配置shiro的ehcache缓存管理器:缓存认证等信息:(可选)
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!--Ehcache缓存配置文件为空则使用默认配置-->
<property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
</bean>
- 配置shiro的会话管理器(可选:默认ServletContainerSessionManager)
<bean id="shiroSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="600000"/> <!-- session 有效时间为半小时 (毫秒单位)-->
<property name="sessionListeners">
<list>
<bean class="com.zhiwei.shiro.listener.sessionLisenter"/>
</list>
</property>
</bean>
- 配置shiro的realm对象:提供shiro认证/授权数据的数据域对象
<bean id="myRealm" class="com.zhiwei.shiro.realm.MyRealm" init-method="setCredentialMatcher"/>
- 配置shiro的安全管理器
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<property name="sessionManager" ref="shiroSessionManager"/>
<property name="realm" ref="myRealm"/>
<!-- AuthenticationListener在认证器里面维护 -->
<property name="authenticator.authenticationListeners">
<set>
<bean class="com.zhiwei.shiro.listener.DefineAuthenticationListener"/>
</set>
</property>
</bean>
- 配置shiro的ShiroFilterFactoryBean(真正处理客户端请求的类)
- securityManager:安全管理器
- loginUrl:登陆页面
- successUrl:登陆成功页面
- unauthorizedUrl:授权失败跳转的页面
- filterChainDefinitions:过滤器链
注意过滤器的工作顺序:shiro采取第1次匹配优先,第一次匹配后后面的过滤器链不会匹配,顺序不当可能出现"302 not found"错误
常用过滤器通俗解释:(过滤路径支持ant风格)
- logout :退出登陆过滤器:默认跳转项目根路径访问地址(可自定义)
- anon:匿名过滤器:不需要认证就可以进行访问:例如公司的首页
- authc:认证过滤器:客户端只有认证通过之后才能访问(例如个人信息)
- roles:权限过滤器:客户端访问制定路径,只有满足指定的角色才能访问
千万注意:名称必须与web.xml配置的Filter名称一致,否则IOC找不到对应的Bean出现异常
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/toLoginPage"/>
<property name="successUrl" value="/toSuccessfulPage"/>
<property name="unauthorizedUrl" value="/toUnauthorizedPage"/>
<property name="filterChainDefinitions">
<value>
/shiroHandler/shiro-logout = logout
/shiroHandler/shiro-login = anon
/toUserPage = authc,roles[user]
/toAdminPage = authc,roles[admin]
/** = authc
</value>
</property>
</bean>
- 配置shiro组件在具备IOC Bean的生命周期活动 (传统的Filter的生命周期是由servlet容器进行统一管理,因为DelegatingFilterProxy的缘故,实际处理客户端请求是IOC容器里面的Filter,因此shiro的实际处理客户端请求的过滤器需要属于IOC的Bean组件,因此最好将其生命周期活动交给IOC容器同一管理)
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
补充: 配置文件AuthenticationListener/SessionListener配置
AuthenticationListener:认证监听器:会负责监听整个shiro认证过程的情况,对于一些项目想统计用户登陆的请求,可以使用该接口,该接口在AuthenticatingSecurityManager的Authenticator中的authenticationListeners维护,DefaultWebSecurityManager因继承了AuthenticatingSecurityManager:使用级联属性配置authenticator.authenticationListeners即可:
AuthenticationListener接口:
public interface AuthenticationListener {
void onSuccess(AuthenticationToken token, AuthenticationInfo info);
void onLogout(PrincipalCollection principals);
}
spring配置AuthenticationListener:authenticator.authenticationListeners
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="authenticator.authenticationListeners">
<set>
<bean class="com.zhiwei.shiro.listener.DefineAuthenticationListener"/>
</set>
</property>
</bean>
SessionListener:会话监听器:顾名思义就是监听整个会话的操作过程在SessionManager中的sessionListeners维护:
SessionListener 接口:
public interface SessionListener {
void onStart(Session session);
void onStop(Session session);
void onExpiration(Session session);
}
spring配置SessionListener :sessionListeners
<bean id="shiroSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionListeners">
<list>
<bean class="com.zhiwei.shiro.listener.sessionLisenter"/>
</list>
</property>
</bean>