个人觉得,上篇中讲到的注解的方式来控制方法的访问权限并没有那么灵活,且需要在代码中硬编码,复用性不高,移植会很麻烦,故研究了下从数据库中动态加载权限

即shiro.xml中的ShiroFilterFactoryBean,之前是直接加载apache源码的bean:<bean id="shiroFilter" class="cn.cjq.util.shiro.ShiroPermissionFactory">

现在做出以下自定义shiro的filter   该bean继承ShiroPermissionFactory,重写父类的setFilterChainDefinitions(java.lang.String definitions)方法

首先来看ShiroPermissionFactory源码,配置文件中的property 都是在为ShiroPermissionFactory属性赋值

源码部分:

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  // IntelliJ API Decompiler stub source generated from a class file  // Implementation of methods is not available

package org.apache.shiro.spring.web;

public class ShiroFilterFactoryBean implements org.springframework.beans.factory.FactoryBean, org.springframework.beans.factory.config.BeanPostProcessor {    private static final transient org.slf4j.Logger log;    private org.apache.shiro.mgt.SecurityManager securityManager;    private java.util.Map<java.lang.String,javax.servlet.Filter> filters;    private java.util.Map<java.lang.String,java.lang.String> filterChainDefinitionMap;    private java.lang.String loginUrl;    private java.lang.String successUrl;    private java.lang.String unauthorizedUrl;    private org.apache.shiro.web.servlet.AbstractShiroFilter instance;

    public ShiroFilterFactoryBean() { /* compiled code */ }

    public org.apache.shiro.mgt.SecurityManager getSecurityManager() { /* compiled code */ }

    public void setSecurityManager(org.apache.shiro.mgt.SecurityManager securityManager) { /* compiled code */ }

    public java.lang.String getLoginUrl() { /* compiled code */ }

    public void setLoginUrl(java.lang.String loginUrl) { /* compiled code */ }

    public java.lang.String getSuccessUrl() { /* compiled code */ }

    public void setSuccessUrl(java.lang.String successUrl) { /* compiled code */ }

    public java.lang.String getUnauthorizedUrl() { /* compiled code */ }

    public void setUnauthorizedUrl(java.lang.String unauthorizedUrl) { /* compiled code */ }

    public java.util.Map<java.lang.String,javax.servlet.Filter> getFilters() { /* compiled code */ }

    public void setFilters(java.util.Map<java.lang.String,javax.servlet.Filter> filters) { /* compiled code */ }

    public java.util.Map<java.lang.String,java.lang.String> getFilterChainDefinitionMap() { /* compiled code */ }

    public void setFilterChainDefinitionMap(java.util.Map<java.lang.String,java.lang.String> filterChainDefinitionMap) { /* compiled code */ }

    public void setFilterChainDefinitions(java.lang.String definitions) { /* compiled code */ }

    public java.lang.Object getObject() throws java.lang.Exception { /* compiled code */ }

    public java.lang.Class getObjectType() { /* compiled code */ }

    public boolean isSingleton() { /* compiled code */ }

    protected org.apache.shiro.web.filter.mgt.FilterChainManager createFilterChainManager() { /* compiled code */ }

    protected org.apache.shiro.web.servlet.AbstractShiroFilter createInstance() throws java.lang.Exception { /* compiled code */ }

    private void applyLoginUrlIfNecessary(javax.servlet.Filter filter) { /* compiled code */ }

    private void applySuccessUrlIfNecessary(javax.servlet.Filter filter) { /* compiled code */ }

    private void applyUnauthorizedUrlIfNecessary(javax.servlet.Filter filter) { /* compiled code */ }

    private void applyGlobalPropertiesIfNecessary(javax.servlet.Filter filter) { /* compiled code */ }

    public java.lang.Object postProcessBeforeInitialization(java.lang.Object bean, java.lang.String beanName) throws org.springframework.beans.BeansException { /* compiled code */ }

    public java.lang.Object postProcessAfterInitialization(java.lang.Object bean, java.lang.String beanName) throws org.springframework.beans.BeansException { /* compiled code */ }

    private static final class SpringShiroFilter extends org.apache.shiro.web.servlet.AbstractShiroFilter {        protected SpringShiroFilter(org.apache.shiro.web.mgt.WebSecurityManager webSecurityManager, org.apache.shiro.web.filter.mgt.FilterChainResolver resolver) { /* compiled code */ }    }}------------------------------------------------------------------------------------------------------------------------------------------------
shiro.xml配置部分内容<!-- 自定义shiro的filter --><bean id="shiroFilter" class="cn.cjq.util.shiro.ShiroPermissionFactory">   <property name="securityManager" ref="securityManager"/>   <property name="loginUrl" value="/login/toLogin.do"/>   <property name="unauthorizedUrl" value="/login/403.do"/>   <property name="filters">      <map>         <entry key="authc" value-ref="formAuthenticationFilter"/>      </map>   </property><property name="filterChainDefinitions">     //该部分的值被重写,部分数据从数据库加载      <value>         /login/**=anon         /api/** = authc         /main.do = authc      </value>   </property></bean>------------------------------------------------------------------------------------------------------------------------------------自定义的shiro拦截器ShiroPermissionFactory
package cn.cjq.util.shiro;import cn.cjq.entity.Menu;import cn.cjq.service.user.UserService;import org.apache.shiro.config.Ini;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.util.CollectionUtils;import org.apache.shiro.web.config.IniFilterChainResolverFactory;import javax.annotation.Resource;import java.util.List;

public class ShiroPermissionFactory extends ShiroFilterFactoryBean {

    /**配置中的过滤链*/    public static String definitions;

    /**权限service*/    @Resource    private UserService userServiceImpl;

    /**     * 从数据库动态读取权限     */    @Override    public void setFilterChainDefinitions(String definitions) {ShiroPermissionFactory.definitions = definitions;

        //数据库动态权限        List<Menu> Menulist= null;        try {            Menulist = userServiceImpl.ListMenu();        } catch (Exception e) {            e.printStackTrace();        }//拼接所有请求(即url)所需要的权限(认证,权限ID),拼接时必须加入\n用来换行,否则无效。        for(Menu menu : Menulist){            //字符串拼接权限 definitions = definitions+menu.getUrl() + " = "+"authc,perms["+menu.getMenuid()+"]\n";        }

        //从配置文件加载权限配置        Ini ini = new Ini();        ini.load(definitions);        Ini.Section section = ini.getSection(IniFilterChainResolverFactory.URLS);        if (CollectionUtils.isEmpty(section)) {            section = ini.getSection(Ini.DEFAULT_SECTION_NAME);        }

        //加入权限集合        setFilterChainDefinitionMap(section);    }

    /**     * 从数据库动态加载权限     *///     public ShiroFilterFactoryBean getShiroFilterFactoryBean() {//        ShiroFilterFactoryBean shiroFilterFactoryBean=null;//        try {//            shiroFilterFactoryBean = new MyShiroFilterFactoryBean();//            //下列属性在配置文件中已配置            shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());            shiroFilterFactoryBean.setLoginUrl("/login");            shiroFilterFactoryBean.setSuccessUrl("/index.html");            shiroFilterFactoryBean.setUnauthorizedUrl("/403");//            loadShiroFilterChain(shiroFilterFactoryBean);//        } catch (Exception e) {//            e.printStackTrace();//        }//        return shiroFilterFactoryBean;//    }////    private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean) throws Exception {//        List<Menu> Menulist = userServiceImpl.ListMenu();//        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();//        for (Menu menu : Menulist) {//            filterChainDefinitionMap.put(menu.getUrl(),"authc,perms["+menu.getMenuid()+"]");//        }//        //配置文件中已配置        filterChainDefinitionMap.put("/login", "anon");//        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);//    }}
-------------------------------------------------------------------------------------------------------------------------------上述列出的是所有url所需的相对应权限ID,下面是自定义realm中的授权信息,列出当前用户所有的权限ID,通过比较是否存在权限问题。(也可通过角色去比较,暂不做说明)
/**    * 授权信息    */   @Override   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {      String username = (String)principals.getPrimaryPrincipal();        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();//    UserService userService = (UserService) SpringContextUtil.getBean("userServiceImpl");        try {         authorizationInfo.setRoles(userMapper.findUserRoles(username));authorizationInfo.setStringPermissions(userMapper.findUserPermissions(username));      } catch (Exception e) {

         e.printStackTrace();      }      return authorizationInfo;   }
------------------------------------------------------------------------------------------------------------------------------------------根据当前用户获取所有权限ID:也可以不根据权限ID,使用别的也可,但必须统一,既然是使用了权限ID,所有查询结果返回权限ID即可
<!-- 根据用户名查询获取权限列表ID --><select id="findUserPermissions" resultType="java.lang.String" parameterType="java.lang.String" >  SELECT  m.menuId  FROM  mif_user u  LEFT JOIN mif_role_user_ref ur ON u.uerId=ur.userId  LEFT JOIN mif_role r ON r.roleId=ur.roleId  LEFT JOIN mif_role_authority_ref ar ON ar.roleId=r.roleId  LEFT JOIN mif_authority a ON a.authorityId=ar.authorityId  LEFT JOIN mif_authotity_menu_ref mr ON mr.authorityId=ar.authorityId  LEFT JOIN mif_menu m ON m.menuId=mr.menuId  WHERE  u.isdelete = 0 AND r.isdelete=0 AND a.isdelete=0 AND m.isdelete=0 AND u.userName = #{0}</select>
--------------------------------------------------------------------------------------------------------------------------------------------坑1:上述标红的\n未使用,无效果坑2:在初始化静态拦截的时候存在初始值/person/**= authc,即/person下的所有方法只要通过认证即可请求。但是shiro权限中数据库的动态数据也包含了/person下的方法,是无效的,原因是自定义的shiro的filter先加载配置文件中的数据,再加载数据库动态数据,存在/person/**= authc在前面时会让部分数据库/person下的url失效,注释掉/person/**= authc即可
 <property name="filterChainDefinitions">     //该部分的值被重写,部分数据从数据库加载      <value>         /login/**=anon         /api/** = authc         /main.do = authc /person/**= authc      </value>   </property>坑3:该bean只会在系统启动时加载一次,之后不会调用,所有存在任何权限上的变动时,需手动调用setFilterChainDefinitions()方法PS:要记住在增删改权限数据库时记得调用setFilterChainDefinitions()方法重新加载相关url:http://blog.csdn.net/u010351766/article/details/70432227

转载于:https://www.cnblogs.com/1234cjq/p/8080156.html

续上篇---shiro从数据库获取动态权限-cjq相关推荐

  1. shiro的集群动态权限更新

    shiro的动态权限,一般都是将权限放在数据库中,项目启动后将权限加载给shiro 当数据库的权限数据发生改变时,重新加载权限给shiro. 单机这样做没问题,但是当项目服务是集群的时候,比如有tom ...

  2. java 接口权限控制_手把手教你搞定权限管理,结合Spring Security实现接口的动态权限控制!...

    SpringBoot实战电商项目mall(30k+star)地址:github.com/macrozheng/- 摘要 权限控管理作为后台管理系统中必要的功能,mall项目中结合Spring Secu ...

  3. SpringBoot+SpringSecurity+RBAC+JWT实现动态权限框架

    一.创建数据库表 DROP TABLE IF EXISTS luo_admin; CREATE TABLE luo_admin ( id bigint(20) NOT NULL AUTO_INCREM ...

  4. SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)...

    SpringBoot整合mybatis.shiro.redis实现基于数据库的细粒度动态权限管理系统实例 shiro 目录(?)[+] 前言 表结构 maven配置 配置Druid 配置mybatis ...

  5. shiro利用mysql动态授权_SpringBoot+Shiro学习之数据库动态权限管理和Redis缓存

    发现问题,需找解决思路. 之前我们整合Shiro,完成了登录认证和权限管理的实现,登录认证没什么说的,需要实现AuthorizingRealm中的doGetAuthenticationInfo方法进行 ...

  6. SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例...

    SpringBoot整合mybatis.shiro.redis实现基于数据库的细粒度动态权限管理系统实例 shiro 目录(?)[+] 1.前言 本文主要介绍使用SpringBoot与shiro实现基 ...

  7. SpringBoot 整合 Shiro 实现动态权限加载更新+ Session 共享 + 单点登录

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源: juejin.im/post/5d087d60518825 ...

  8. SpringBoot 整合Shiro实现动态权限加载更新+Session共享+单点登录

    作者:Sans_ juejin.im/post/5d087d605188256de9779e64 一.说明 Shiro是一个安全框架,项目中主要用它做认证,授权,加密,以及用户的会话管理,虽然Shir ...

  9. 【OkHttp】OkHttp 上传图片 ( 获取 SD 卡动态权限 | 跳转到相册界面选择图片 | 使用 OkHttp 上传图片文件 )

    OkHttp 系列文章目录 [OkHttp]OkHttp 简介 ( OkHttp 框架特性 | Http 版本简介 ) [OkHttp]Android 项目导入 OkHttp ( 配置依赖 | 配置 ...

最新文章

  1. 疯狂ios讲义疯狂连载之游戏的状态数据模型
  2. 社会主义基本经济规律是经济效益规律
  3. python load_Python实例:numpy.load()的使用
  4. MariaDB基础(二)
  5. 人人都需要专利的原因
  6. 中国凝血测试耗材行业市场供需与战略研究报告
  7. ROS学习:智能车室外光电组仿真
  8. 鱼C论坛_VIP二号光盘
  9. 深入理解 Python 异步编程(上)
  10. Hibernate中Criteria的完整用法2
  11. 禁止国外IP连接服务器
  12. 机器视觉培训教程-硬件选型
  13. 深圳计算机职称叫什么,深圳职称是什么
  14. 大数据处理框架的类型、比较和选择
  15. HDU 2209 翻纸牌游戏 By Assassin 模拟
  16. java 屏蔽广告js_手机端JS屏蔽广告
  17. 如何下载Figma(肥姑妈)
  18. 视觉SLAM——特征点法与直接法对比以及主流开源方案对比 LSD SVO ORB DSO
  19. vue项目使用域名部署(一个域名多个项目)
  20. java 上传文件-生成文件首页缩略图 生成pdf 抓取图片

热门文章

  1. border-image用法
  2. SpringBoot实现定时任务
  3. ES6公用花瓣飘落插件的封装及使用,支持npm安装
  4. 安卓SDK之YUV-Image
  5. Computer Vision的尴尬
  6. js Blob对象介绍
  7. webpack的build的时候时间长处理方案
  8. 梓益C语言学习笔记之指针
  9. js简单验证码的生成和验证
  10. python OpenGL 安装