栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot集成shiro重写权限验证规则,动态加载权限

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot集成shiro重写权限验证规则,动态加载权限

shiro的对接口权限的控制,一般都是在接口上加注解,每次进行请求时,在realm中加载用户的角色信息,由角色信息判断是否拥有对该接口的访问权限,无法动态的增加和删除角色对应的接口权限,也无法动态的增加接口绑定的角色权限信息

为此重写shiro的权限过滤器能帮助我们去实现自己的权限过滤规则,动态的改变权限,为角色增加和减去权限

shiro的过滤器类别

1.重写shiro的权限过滤器PathMatchingFilter继承该类
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.project.User.entity.Result;
import com.project.User.entity.SysMenuEntity;
import com.project.User.mapper.SysMenuDao;
import com.project.User.mapper.UserInfoMapper;
import com.project.User.service.Impl.SysMenuServiceImpl;
import com.project.User.service.SysMenuService;
import com.project.User.service.UserInfoService;
import com.project.config.sys.RedisPreloadData;
import com.project.utils.JWTUtils;
import com.project.utils.SpringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.WebApplicationContextUtils;


@Component
public class CustomisedURLPathMatchingFilter extends PathMatchingFilter {

    @Autowired
    SysMenuService sysMenuService;

    @Autowired
    //将权限信息缓存到redis
    RedisTemplate redisTemplate;

    @Override
    public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue)
            throws Exception {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        httpServletResponse.setCharacterEncoding("UTF-8");

        String tokens = httpServletRequest.getHeader("Authorization");
        
        
        if(sysMenuService==null){
            sysMenuService = (SysMenuService) SpringUtils.getBean("SysMenuService");
        }
        if(redisTemplate == null){
            redisTemplate = (RedisTemplate) SpringUtils.getBean("redisTemplate");
        }

        // 获取请求的地址URI
        String requestURI = getPathWithinApplication(request);
        if (requestURI == null || requestURI.trim().equals("")){
            httpServletResponse.getWriter().write(JSON.toJSONString(Result.error(403,"无权限访问",null)));
            return false;
        }

        Subject subject = SecurityUtils.getSubject();
        
        if (!subject.isAuthenticated()) {
            httpServletResponse.getWriter().write(JSON.toJSONString(Result.error(401,"未登录",null)));
            return false;
        }

        
        ReleaseMap releaseMap = (ReleaseMap) SpringUtils.getBean("ReleaseMap");
        Map passMap = releaseMap.getReleaseMap();
        Set strings = passMap.keySet();
        for(String url:strings){
            if(url!=null){
                if(requestURI.contains(passMap.get(url))){
                    return true;
                }
            }
        }

        
        String token = httpServletRequest.getHeader("Authorization");
        
        Integer userid = JWTUtils.getIntUser(token, "userid");
        
        List menuUrl = JSONObject.parseArray((String)
                redisTemplate.opsForValue().get(RedisPreloadData.ROLE_URL+userid),SysMenuEntity.class);
        if(menuUrl == null){
            menuUrl = sysMenuService.getMenuUrl(userid);
        }
        
        for(SysMenuEntity entity:menuUrl){
            if(entity.getUrl()==null || "".equals(entity.getUrl())){continue;}
            if(requestURI.contains(entity.getUrl())){
                return true;
            }
        }
        httpServletResponse.getWriter().write(JSON.toJSONString(Result.error(403,"无权限访问",null)));
        return false;
    }
}
2.StringUtil.java获取加载好的bean
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringUtils.applicationContext == null){
            SpringUtils.applicationContext  = applicationContext;
        }
    }


    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static  T getBean(Class clazz){
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static  T getBean(String name,Class clazz){
        return getApplicationContext().getBean(name, clazz);
    }

}
3.完成 了过滤器的编写后,需在shiro的配置文件中shiroConfig.java加载该过滤器,下面贴出部分shiro的配置文件方法
 
    @Bean()
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);


        // 添加自己的过滤器并且取名为jwt
        //自定义权限拦截器roles
        Map filterMap = new HashMap<>();
        filterMap.put("jwt", new JWTFilter());
        filterMap.put("roles", new CustomisedURLPathMatchingFilter());
        factoryBean.setFilters(filterMap);

        Map filterRuleMap = new HashMap<>();
        filterRuleMap.put("/**", "noSessionCreation,jwt,roles");
        // 访问401和404页面不通过我们的Filter
        filterRuleMap.put("/404", "anon");
        filterRuleMap.put("/druid/**", "anon");
        filterRuleMap.put("/swagger-ui.html/**", "anon");
        filterRuleMap.put("/webjars/**", "anon");
        filterRuleMap.put("/swagger-resources/**", "anon");
        filterRuleMap.put("/configuration/security", "anon");
        filterRuleMap.put("/configuration/ui", "anon");
        filterRuleMap.put("/v2/api-docs", "anon");
        filterRuleMap.put("/land/common/kaptcha", "anon");
        filterRuleMap.put("/land/login", "anon");
        filterRuleMap.put("/land/logout", "anon");

        factoryBean.setFilterChainDefinitionMap(filterRuleMap);
        return factoryBean;
    }

注意shiro配置文件中map的拦截或放行顺序

看完整实例代码
码云:https://gitee.com/hydrogenated-oxygen/erpshiro
欢迎指正不足,共同进步

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/343735.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号