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。

原文地址:https://www.cnblogs.com/woms/p/5993790.html