Shiro集成spring--权限管理

时间:2021-10-18 15:20:21

Shiro与Spring Security类似是都是用作权限管理,它们的控制粒度都能达到按钮级别。其实在正常使用中已经足够了,那么本次主要记录一下Shiro和Spring的集成,具体如下:


Shiro是通过过滤器的方式,对访问路径拦截,并进行权限的控制。那么首先,需要在web.xml中设置一个过滤器

<!-- 配置shiro   start -->
    <!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 -->   
	<!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter"/> -->   
	<!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 -->   
	<!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的      -->  
	<filter>        
	    <filter-name>shiroFilter</filter-name>       
	    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>       
        <init-param>  
      		<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->             
        	<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>
	<!--配置shiro   end -->

以上我们看到一个代理过滤器shiroFilter,这个shiroFilter实在spring中使用bean的形式定义的
<!-- 这个id得和web.xml中shiro的filter-name相对应 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
	    <!-- Shiro的核心安全接口,这个属性是必须的 -->  
	    <property name="securityManager" ref="securityManager"/>  
	    <!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面    -->
	    <property name="loginUrl" value="/toLogin.do"/> 
	    <!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码为main.jsp了) 
	    <property name="successUrl" value=""/>  -->  
	    <!-- 用户访问未对其授权的资源时,所显示的连接 -->  
	    <!-- 若想更明显的测试此属性可以修改它的值,如unauthor.jsp-->  
	    <property name="unauthorizedUrl" value="/unauth.do"/>  
	    <!-- Shiro连接约束配置,即过滤链的定义 -->  
	    <!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath()项目路径的值来的 -->  
	    <!-- anon:它对应的过滤器里面是空的,什么都没做,不验证,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 -->  
	    <!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->  
	    <property name="filterChainDefinitions">  
	        <value>  
				 /toLogin**=anon       <!-- 不需要验证 -->
	             /login**=anon       <!-- 不需要验证 -->
				 /unauth**=anon       <!-- 不需要验证 -->
	             /mycode.jpg=anon  
	             /static/** = anon
	             /common/** = anon
	             /service/** = anon
	             /** = authc       <!-- 需要认证 --> 
	        </value>  
	    </property>
	</bean>
以上每个参数注释已经很详细,就不再多舌。shiroFilter的配置还需要一个安全处理的核心securityManager,具体配置如下:
<!--安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--设置自定义Realm-->
        <property name="realm" ref="shiroDbRealm"/>
    </bean>
<!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的ShiroDbRealm.java --> 
    <bean id="shiroDbRealm" class="com.enker.manager.shiro.ShiroDbRealm">
        
    </bean>
以上安全管理器还需要一个realm,其实这个类中主要是用来进行登录验证及权限验证的。这个需要我们自己独立实现,继承与AuthorizingRealm,主要实现两个方法

//登录验证

protected AuthenticationInfo doGetAuthenticationInfo

//权限验证

protected AuthorizationInfo doGetAuthorizationInfo


当然除了以上配置实现外,还需要配置:

<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->  
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
	    <property name="proxyTargetClass" value="true" />
	</bean>
LifecycleBeanPostProcessor用于在实现了Initializable接口的Shiro bean初始化时调用Initializable接口回调,在实现了Destroyable接口的Shiro bean销毁时调用 Destroyable接口回调。如UserRealm就实现了Initializable,而DefaultSecurityManager实现了Destroyable。具体可以查看它们的继承关系。



在登录代码中我们还需要手动调用login方法,执行登录操作。具体如下:

UsernamePasswordToken token = new UsernamePasswordToken(userName,password,rememberMe);
				SecurityUtils.getSubject().login(token);


可能参考博文:http://jinnianshilongnian.iteye.com/blog/2029717/