shiro授权功能实例

shiro授权功能实例


一、在配置文件中,配置需要权限信息

<?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="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="loginUrl" value="/login.html" />
		<property name="unauthorizedUrl" value="/error.html" />
		<property name="filters">
			<map>
				<entry key="perms" value-ref="erpAuthorizationFilter"></entry>
			</map>
		</property>
		<property name="filterChainDefinitions">
			<value>
				/error.html = anon
				/login_*.action = anon
				/login_* = anon
				/emp_updatePwd.action=perms[]
				/*_get.action=perms[]
				/*_list.action=perms[]
				/*_listByPage.action=perms[]
				/*_myListByPage.action=perms[]

				/goodstype.html=perms["商品类型"]
				/goodstype_*.action=perms["商品类型"]

				/goods.html=perms["商品"]
				/goods_*.action=perms["商品"]

				/store.html=perms["仓库"]
				/store_*.action=perms["仓库"]

				/supplier.html=perms["供应商管理","客户管理"]
				/supplier_*.action=perms["供应商管理","客户管理"]

				/dep.html=perms["部门"]
				/dep_*.action=perms["部门"]

				/emp.html=perms["员工"]
				/emp_*.action=perms["员工"]

				/orders.html=perms["采购申请","采购订单查询","采购订单审核","采购订单确认","采购订单入库","销售订单查询","销售订单录入","销售订单出库"]
				/orders_*.action=perms["采购申请","采购订单查询","采购订单审核","采购订单确认","采购订单入库","销售订单查询","销售订单录入","销售订单出库"]
				/orders_add.action=perms["采购申请",销售订单录入]
				/orders_doCheck.action=perms["采购订单审核"]
				/orders_doStart.action=perms["采购订单确认"]
				/store_myList.action=perms["采购订单入库","销售订单出库"]
				/orderdetail_doInStore=perms["采购订单入库"]
				/orderdetail_doOutStore=perms["销售订单出库"]

				/storedetail.html=perms["库存查询"]
				/storeoper.html=perms["库存变动记录"]

				/returnorders.html=perms["退货订单登记","退货订单查询","退货订单审核","退货订单出库"]
				/returnorders_*.action=perms["退货订单登记","退货订单查询","退货订单审核","退货订单出库"]
				/returnorders_add.action=perms["退货订单登记"]
				/returnorders_doCheck.action=perms["退货订单审核"]
				/returnorders_doOutStore.action=perms["退货订单出库"]

				/pwd.html=perms["重置密码"]
				/emp_updatePwd_reset.action=perms["重置密码"]
				
				/returnorders1.html=perms["销售退货登记","销售退货查询","销售退货审核","销售退货入库"]
				/returnorders1_*.action=perms["销售退货登记","销售退货查询","销售退货审核","销售退货入库"]
				/returnorders1_add.action=perms["销售退货登记"]
				/returnorders1_doCheck.action=perms["销售退货审核"]
				/returnorders1_doInStore.action=perms["销售退货入库"]

				/inventory.html=perms["盘盈盘亏登记","盘盈盘亏审核","盘盈盘亏查询"]
				/inventory_*.action=perms["盘盈盘亏登记","盘盈盘亏审核","盘盈盘亏查询"]
				/inventory_add.action=perms["盘盈盘亏登记"]
				/inventory_doCheck.action=perms["盘盈盘亏审核"]


				/report_order.html=perms["销售统计表"]
				/report_order*.action=perms["销售统计表"]

				/report_trend.html=perms["销售趋势分析"]
				/report_trend*.action=perms["销售趋势分析"]

				/storealert.html=perms["库存预警"]
				/storealert*.action=perms["库存预警"]


				/role.html=perms["角色管理"]
				/role*.action=perms["角色管理"]

				/emp_roleSet.html=perms["员工角色设置"]
				/emp_readEmpRoleList.action=perms["员工角色设置"]
				/emp_updateEmpRoleList.action=perms["员工角色设置"]

				/role_menuSet.html=perms["角色权限设置"]
				/role_readRoleMenuList.action=perms["角色权限设置"]
				/role_updateRoleMenuList.action=perms["角色权限设置"]

				/*.html = authc
				/*.action = authc
				/* = authc
			</value>
		</property>
	</bean>

	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="erpRealm"></property>
	</bean>

	<!-- 配置自定的Realm -->
	<bean id="erpRealm" class="cn.itcast.erp.realm.ErpRealm">
		<property name="empBiz" ref="empBiz"></property>
 	</bean>

	<!-- 注册自定义授权过滤器 -->
	<bean id="erpAuthorizationFilter" class="cn.itcast.erp.filter.ErpAuthorizationFilter"></bean>


</beans>

注意:由于我们这里的系统需求,一个url有多个权限信息的时候,只要满足其一,即可。所以我们需要自定义授权过滤器,并配置在配置文件中。


二、书写授权方法(ErpRealm中的doGetAuthorizationInfo方法)

    /**
     * 授权方法
     *
     * @param principalCollection
     * @return org.apache.shiro.authz.AuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取当前登录用户的菜单权限
        Emp loginUser = (Emp) principalCollection.getPrimaryPrincipal();
        List<Menu> menuLis = empBiz.getMenusByEmpuuid(loginUser.getUuid());
        //加入到授权信息中
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        for(Menu m : menuLis) {
            //将权限放入授权信息中
            info.addStringPermission(m.getMenuname());
        }

        return info;
    }


三、书写自定义过滤器

package cn.itcast.erp.filter;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 自定义授权过滤器
 * Author xushuai
 * Description
 */
public class ErpAuthorizationFilter extends AuthorizationFilter {

    /**
     * 是否有访问权限
     *
     * @param servletRequest
	 * @param servletResponse
	 * @param mappedValue perms[]中的权限信息,可能为多个
     * @return boolean
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object mappedValue)
            throws Exception {
        //获取操作主题
        Subject subject = getSubject(servletRequest,servletResponse);
        //获取配置文件中的权限列表
        String[] permsList = (String[]) mappedValue;

        boolean isPermitted = true;
        if(permsList == null || permsList.length == 0) {
            return isPermitted;
        }
        //检查其权限
        if(permsList != null && permsList.length > 0) {
            for(String perms : permsList) {
                //只要满足一个权限信息,就返回true
                if(subject.isPermitted(perms)) {
                    return isPermitted;
                }
            }
        }

        return false;
    }
}


在书写配置文件的时候,ShiroFilterFactoryBean中的 filters 属性的类型为map,要想使我们自定义的Filter生效,使用key值替换掉原先的Filter,这里我们需要替换掉perms的值。

Shiro的过滤器:第一列为key,第二列为对应的Filter类

anon

org.apache.shiro.web.filter.authc.AnonymousFilter

authc

org.apache.shiro.web.filter.authc.FormAuthenticationFilter

authcBasic

org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter

perms

org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter

port

org.apache.shiro.web.filter.authz.PortFilter

rest

org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter

roles

org.apache.shiro.web.filter.authz.RolesAuthorizationFilter

ssl

org.apache.shiro.web.filter.authz.SslFilter

user

org.apache.shiro.web.filter.authc.UserFilter




四、shiro缓存管理器

(1)为什么要配置缓存管理器

因为shiro的授权方法的调用时机,是在每次访问需要权限的url时,都会进行授权方法,这样会非常浪费资源,且权限信息基本上不会怎么变动,所以我们采用缓存机制。

(2)我们使用shiro自带的Ehcache缓存。当然也可以使用redis以及其他容器做缓存。
(3)使用Ehcache做缓存,必须要导入shiro的完整依赖。
		<!-- 引入shiro框架的依赖 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-all</artifactId>
			<version>${shiro.ver}</version>
		</dependency>
(4)使用Ehcache只需要进行简单的配置即可使用。但是需要准备一个ehcache的配置文件。
(5)ehcache.xml配置文件
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <!-- 配置临时文件目录位置 -->
    <diskStore path="java.io.tmpdir"/>

    <!--
 	   	相关属性配置:
 	   		maxElementsInMemory : 在内存中最多可存储的元素(即多少个JAVA对象)
 	   		eternal : 缓存的数据是否永久有效
 	   		timeToIdleSeconds : 最大空闲时间(单位:秒),超时将清理缓存数据
            timeToLiveSeconds : 最大有效时间(单位:秒),超时将清理缓存数据
            overflowToDisk : 内存溢出存入磁盘,即存入临时文件目录
            maxElementsOnDisk : 存入磁盘的元素最大值
            diskPersistent : 重启服务器时,磁盘上的数据是否持久化
            diskExpiryThreadIntervalSeconds : 缓存清理线程的执行周期,即每多少秒清理一次多余的失效的数据
            memoryStoreEvictionPolicy : 淘汰策略(LRU->最近最少优先。   FIFO->先进先出)
     -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
    />
</ehcache>
(6)配置缓存管理器,并交给shiro安全管理器管理


猜你喜欢

转载自blog.csdn.net/qq1031893936/article/details/80885084