zoukankan      html  css  js  c++  java
  • Shiro【常用的自定义】

    一、前言

    在实际开发中,默认的配置往往不满足业务需求,所以就需要进行一些自定义。

    二、自定义 Filter

    (一)为什么要自定义

    在 ShiroConfig 配置类中我们有配置指定角色才能访问的路径,如:

    filterChainDefinitionMap.put("/admin/**", "roles[admin]");
    

    但如果我们多加入一个 root 角色的话,如:

    filterChainDefinitionMap.put("/admin/**", "roles[admin,root]");
    

    就会要求当前登录的用户必须同时满足这两个角色才能访问。

    这其实是不符合需求的,所以我们需要自定义 Filter ,修改其授权的逻辑,实现只需要满足其中任意一个角色就可以访问。

    (二)步骤
    1. 编写 Filter 类,继承 AuthorizationFilter 类;

    2. 重写 isAccessAllowed 方法

    3. 在 ShiroConfig 配置类中进行配置

    (三)代码实现
    1. 编写 Filter 类,继承 AuthorizationFilter 类 :

    2. 重写 isAccessAllowed 方法:

    public class CustomRoleFilter extends AuthorizationFilter {
    
        @Override
        public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
    
            Subject subject = getSubject(request, response);
    
            // 获取 ShiroConfig 配置类中所配置的所有角色
            // 如:filterChainDefinitionMap.put("/admin/**", "roles[admin,root]");
            String[] rolesArray = (String[]) mappedValue;
    
            //如果没有配置角色限制,可以直接访问
            if (rolesArray == null || rolesArray.length == 0) {
                return true;
            }
    
            Set<String> roles = CollectionUtils.asSet(rolesArray);
    
            //当前 subject 是 roles 中的任意一个,则有权限访问
            for(String role : roles){
                if(subject.hasRole(role)){
                    return true;
                }
            }
            return false;
        }
    }
    
    1. 在 ShiroConfig 配置类中进行配置:
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager){
        System.out.println("ShiroFilterFactoryBean加载...");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    
        // 1.设置SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
    
        /**
         设置一些特殊功能的接口路径
        */
        // 其余代码可在项目源码中查看,此处为了篇幅短,故省略
    
        /**
        * 设置自定义拦截器
        */
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("customRoleFilter", new CustomRoleFilter());
        shiroFilterFactoryBean.setFilters(filterMap);
    
        /**
        * 设置拦截路径:对访问路径指定拦截器
        */
        // 其余代码可在项目源码中查看,此处为了篇幅短,故省略
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
    
        // 3.4 角色拦截器(指定角色才可以访问)
        // filterChainDefinitionMap.put("/admin/**", "roles[admin,root]");
        filterChainDefinitionMap.put("/admin/**", "customRoleFilter[admin,root]");
    
    
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
    

    三、自定义 SessionId

    (一)为什么要自定义

    在实际开发中,我们可能不想用默认的格式生成 SessionId,所以可以自己指定。

    (二)步骤
    1. 编写类,实现 SessionIdGenerator 接口

    2. 在 generateId方法中编写生成 sessionId 的代码

    3. 在 SessionDao 中进行设置。由于项目中使用的是 Redis,所以此处需要在 RedisSessionDao 中进行设置

    (三)代码实现
    1. 编写类,实现 SessionIdGenerator 接口:

    2. 在 generateId方法中编写生成 sessionId 的代码:

    public class CustomSessionIdGenerator implements SessionIdGenerator {
        @Override
        public Serializable generateId(Session session) {
            return "shiro_rbac-"+ UUID.randomUUID().toString().replace("-","");
        }
    }
    
    1. 在 SessionDao 中进行设置:
    public RedisSessionDAO redisSessionDAO(){
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(getRedisManager());
    
        //设置 sessionId 生成器
        redisSessionDAO.setSessionIdGenerator(new CustomSessionIdGenerator());
        
        return redisSessionDAO;
    }
    

    四、ShiroConfig 中常用的 Bean

    一些为一些经常在 ShiroConfig 配置类中进行配置的 Bean,了解即可。

    /**
     * 管理shiro一些bean的生命周期 即:bean初始化与销毁
     * @return
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
    
    /**
     *  如果要在 controller 中使用 Shiro 的注解,就必须配置这个 Bean 对象
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(getSecurityManager());
        return authorizationAttributeSourceAdvisor;
    }
    
    /**
     *  用来扫描上下文,寻找所有的Advistor(通知器),
     *  将符合条件的Advisor应用到切入点的Bean中,需要在LifecycleBeanPostProcessor创建后才可以创建
     * @return
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new     DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setUsePrefix(true);
        return defaultAdvisorAutoProxyCreator;
    }
    

    五、项目源代码

    链接: https://pan.baidu.com/s/1fKGMSvEmXBItHD6U_pduhg 提取码: jhwy

    Java新手,若有错误,欢迎指正!

  • 相关阅读:
    关于js中"window.location.href"、"location.href"、"parent.location.href"、"top.location.href"的用法
    对于json数据的应用01
    关于session应用(1)session过期时间设置
    关于session应用(2)JAVA中怎么使用session
    Jquery常用技巧(3)
    0101对称二叉树 Marathon
    0112路径之和 & 0113所有路径之和 Marathon
    0106105从中序与后序遍历序列中构造二叉树 Marathon
    0110平衡二叉树 Marathon
    0513找树左下角的值 Marathon
  • 原文地址:https://www.cnblogs.com/Java-biao/p/14480744.html
Copyright © 2011-2022 走看看