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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM