zoukankan      html  css  js  c++  java
  • shiro权限定义的三种方法

    1.在配置文件中定义

        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <property name="loginUrl" value="/index.jsp" /> <!-- 没有认证返回地址 -->
            <property name="unauthorizedUrl" value="/index2.jsp" /> <!-- 没有授权返回地址 -->
            <property name="filterChainDefinitions">
                <value>            <!-- **代表任意子目录 -->
                /login/** = anon
                /user/** = authc,roles[admin]
                /test/** = authc,perms[测试用的lkkk]
                </value>
            </property>
        </bean>

    2.在数据库中定义

         <bean id="chainDefinitionSectionMetaSource" class="com.fyh.www.shiro.ChainDefinitionSectionMetaSource">
            <property name="filterChainDefinitions"> <!-- 定义默认的url权限 -->
                <value>
                 /login/** = anon
                </value>
            </property>
        </bean> 
    
    
    
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <property name="loginUrl" value="/index.jsp" /> <!-- 没有认证返回地址 -->
            <property name="unauthorizedUrl" value="/index2.jsp" /> <!-- 没有授权返回地址 -->
            <property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource"/>
        </bean>

     Resource.java(数据库对应的pojo)

    public class Resource implements Serializable {
        /**
         * id
         */
        private Integer id;
    
        /**
         * url
         */
        private String value;
    
        /**
         * 所需权限
         */
        private String permission;
    
    //-----------------------getter/setter方法---------------------------//

    ChainDefinitionSectionMetaSource.java(加载pojo)

    }
    
    public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section> {
        
        @Autowired
        private ResourceDao resourceDao;
        
        private String filterChainDefinitions;
        
        
        
        /**
        * 默认premission 字符串格式模板
        */
        public static final String PREMISSION_STRING="perms["{0}"]";
    
        @Override
        public Section getObject() throws Exception {
            //获取所有Resource
            List<Resource> list = resourceDao.getAll();
            Ini ini = new Ini();
            //加载默认的url
            ini.load(filterChainDefinitions);
            Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
            //循环Resource 的url,逐个添加到section 中。section 就是filterChainDefinitionMap,
            //里面的键就是链接URL,值就是存在什么条件才能访问该链接
            for (Iterator<Resource> it = list.iterator(); it.hasNext();) {
            Resource resource = it.next();
            //如果不为空值添加到section 中
            if(StringUtils.isNotEmpty(resource.getValue()) &&
            StringUtils.isNotEmpty(resource.getPermission())) {
            section.put(resource.getValue(),MessageFormat.format(PREMISSION_STRING,resource.getPermission()));
            }
            }
            return section;
        }
    
        
        /**
         * 通过filterChainDefinitions 对默认的url 过滤定义 *
         * 
         * @param filterChainDefinitions 默认的url 过滤定义
         *           
         */
        public void setFilterChainDefinitions(String filterChainDefinitions) {
            this.filterChainDefinitions = filterChainDefinitions;
        }
    
        @Override
        public Class<?> getObjectType() {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public boolean isSingleton() {
            // TODO Auto-generated method stub
            return false;
        }
    
    }

    dao接口

    @Repository
    public interface ResourceDao {
    
        public List<Resource> getAll();
    }
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.fyh.www.dao.shiro.ResourceDao" >
      <resultMap id="BaseResultMap" type="com.fyh.www.pojo.shiro.Resource" >
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="value" property="value" jdbcType="VARCHAR" />
        <result column="permission" property="permission" jdbcType="VARCHAR" />
      </resultMap>
    
      <select id="getAll" resultMap="BaseResultMap"  >
        select 
        id,value,permission
        from TB_RESOURCE
      </select>
     
    </mapper>

    数据库结构

    3.在注解上定义

     开启注解(添加如下配置文件)

     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
              depends-on="lifecycleBeanPostProcessor">
        </bean>
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"/>
        </bean>
    @Controller
    @RequestMapping(value = "/test")
    public class TestController {
        
        
        
        @RequestMapping(value = "/test.action")
        public String test(Model model)  {        
            return SysContant.FRONT_PAGE+"NewFile1";
        }
        
        @RequestMapping("/test2")
        @RequiresPermissions("account:create")
        public String testAnnotation(){
            
            return SysContant.FRONT_PAGE+"NewFile1";
        }
        
    
    }

    可是为什么不生效呢,今天我就来说说这事儿。

     我们知道Shiro的注解授权是利有Spring的AOP实现的。在程序启动时会自动扫描作了注解的Class,当发现注解时,就自动注入授权代码实现。也就是说,要注入授权控制代码,第一处必须要让框架要可以扫描找被注解的Class 。

    applicationContext.xml一般配置注解扫描将@controller注解拉入黑名单

    <context:component-scan base-package="com.fyh.www" >
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>

    apringmvc.xml中配置注解扫描一般只扫描@controller注解

    <context:component-scan base-package="com.fyh.www.controller" use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>

    而我们的Srping项目在ApplicationContext.xml中一般是不扫描Controller的,所以也就无法让写在Controller中的注解授权生效了。因此正确的作法是将这配置放到springmvc的配置文件中.这样Controller就可以通过注解授权了。

    不过问题来了,通过上面的配置Controller是可以通过注解授权了,但是Services中依然不能通过注解授权。虽然说,如果我们在Controller控制了授权,那么对于内部调用的Service层就可以不再作授权,

    但也有例外的情况,比如Service除了给内部Controller层调用,还要供远程SOAP调用,那么就需要对Service进行授权控制了。同时要控制Controller和Service,那么采用相同的方式,我们可以在ApplicationContext.xml中配置类同的配置,以达到相同的效果。

     applicationContext.xml中的配置为:

       <bean id="serviceAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
    <bean id="serviceAuthorizationAttributeSourceAdvisor" class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean>

     apringmvc.xml中的配置为:

       <bean id="controllerAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
              depends-on="lifecycleBeanPostProcessor"/>
    <bean id="controllerAuthorizationAttributeSourceAdvisor" class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean>

    此时,我们在同一个项目中配置了两个,DefaultAdvisorAutoProxyCreator 和AuthorizationAttributeSourceAdvisor.需要给它们指定不同的ID。

  • 相关阅读:
    DataList分页的实现
    request
    MDX as的使用
    GridView加入checkbox
    .net读取excel
    Cousin
    silverlight柱状图 改变选项事件 和 取消选择
    关于DrillThrough
    取最大值的那天MDX
    ConnectionString has already been added(虚拟目录的web.config节点不继承上级目录)
  • 原文地址:https://www.cnblogs.com/woms/p/5993790.html
Copyright © 2011-2022 走看看