shiro的过滤器和权限控制

首页 / 新闻资讯 / 正文

shiro过滤器

首先从客户端发来的所有请求都经过Shiro过滤器,如果用户没有认证的都打回去进行认证,认证成功的,再判断是否具有访问某类资源(公有资源,私有资源)的权限,如果没有权限,访问失败;如果有权限访问成功。注意:客户端传来的token要和realm中的认证信息进行相同规则的比较(加密算法要一致)。
常见过滤器:
shiro的过滤器和权限控制
1、在shiro配置类中配置,使用 filterFactoryBean.setFilterChainDefinitionMa() 简单的配置过滤规则

 @Bean     public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {         // 创建ShiroFilterFactoryBean         ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();         //设置安全管理器         filterFactoryBean.setSecurityManager(defaultWebSecurityManager);         //配置受限资源,index是受限资源,authc         Map<String, String> map = new HashMap<String, String>();         // /**代表匹配所有url         map.put("/**", "authc");         // /user/login 是可以匿名访问的也就是公有资源         map.put("/user/login", "anon");         filterFactoryBean.setFilterChainDefinitionMap(map);          // 设置默认认证路径 其实shiro默认的认证路径就是login.jsp         filterFactoryBean.setLoginUrl("/login.jsp");          return filterFactoryBean;      } 

2、重写shiro提供的过滤器
重写角色权限的过滤器

public class MyAuthorizationFilter extends RolesAuthorizationFilter {      @Override    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)         throws IOException {     boolean allowed =super.isAccessAllowed(request, response, mappedValue);     if (!allowed) {         String method = WebUtils.toHttp(request).getMethod();         if (StringUtils.equalsIgnoreCase("OPTIONS", method)) {             return true;         }     }     return allowed;    }      @Override    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {     HttpServletRequest req = (HttpServletRequest) request;     HttpServletResponse resp = (HttpServletResponse) response;     if (req.getMethod().equals(RequestMethod.OPTIONS.name())) {         resp.setStatus(HttpStatus.OK.value());         return true;     }     // 前端Ajax请求时requestHeader里面带一些参数,用于判断是否是前端的请求     String ajaxHeader = req.getHeader(CustomSessionManager.AUTHORIZATION);     if (StringUtils.isNotBlank(ajaxHeader)) {         // 前端Ajax请求,则不会重定向         resp.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));         resp.setHeader("Access-Control-Allow-Credentials", "true");         resp.setContentType("application/json; charset=utf-8");         resp.setCharacterEncoding("UTF-8");         PrintWriter out = resp.getWriter();         String result = "{"MESSAGE":"角色,权限不足"}";         out.println(result);         out.flush();         out.close();         return false;     }     return super.onAccessDenied(request, response);    } } 

shiro配置类配置过滤器

//Filter工厂,设置对应的过滤条件和跳转条件     @Bean     public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();         shiroFilterFactoryBean.setSecurityManager(securityManager);         Map<String, String> map = new HashMap<>();         //登出         map.put("/logout", "logout");         //对所有用户认证         map.put("/**", "authc");         //登录         log.info("loginUrl:" + loginUrl);         shiroFilterFactoryBean.setLoginUrl(loginUrl); //        //首页 //        shiroFilterFactoryBean.setSuccessUrl("/index");         //错误页面,认证不通过跳转         shiroFilterFactoryBean.setUnauthorizedUrl("/error");         shiroFilterFactoryBean.setFilterChainDefinitionMap(map);          /* 自定义filter注册 */         Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();         //根据上面列表中的过滤器的名称配置         filters.put("roles", new MyAuthorizationFilter());          return shiroFilterFactoryBean;     } 

注意:过滤器需要根据上面列表中的过滤器的名称配置

权限控制

除了在配置类中配置路径的访问权限之外,还可以使用注解来控制权限 。

Shiro注解一共有五个:
shiro的过滤器和权限控制

一般情况下我们在项目中做权限控制,使用最多的是RequiresPermissions和RequiresRoles,允许存在多个角色和权限,默认逻辑是AND,也就是同时拥有这些才可以访问方法,可以在注解中以参数的形式设置成OR。作用在controller类的方法上。

 示例     //拥有一个角色就可以访问     @RequiresRoles(value={"ADMIN","USER"},logical = Logical.OR)     //拥有所有权限才可以访问     @RequiresPermissions(value={"sys:user:info","sys:role:info"},logical = Logical.AND) 

使用顺序:Shiro注解是存在顺序的,当多个注解在一个方法上的时候,会逐个检查,知道全部通过为止,默认拦截顺序是:
RequiresRoles->RequiresPermissions->RequiresAuthentication->RequiresUser->RequiresGuest

动态配置权限

这里指的是动态配置当前登录用户的权限
1、登录时查询当前用户的角色、权限

/**      * 赋予角色和权限:用户进行权限验证时 Shiro会去缓存中找,如果查不到数据,会执行这个方法去查权限,并放入缓存中      */     @Override     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {         SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();         // 获取用户         User user = (User) principalCollection.getPrimaryPrincipal();         Integer userId =user.getId();         // 这里可以进行授权和处理         Set<String> rolesSet = new HashSet<>();         Set<String> permsSet = new HashSet<>();         // 获取当前用户对应的权限(这里根据业务自行查询)         List<Role> roleList = roleMapper.selectRoleByUserId( userId );         for (Role role:roleList) {             rolesSet.add( role.getCode() );             List<Menu> menuList = menuMapper.selectMenuByRoleId( role.getId() );             for (Menu menu :menuList) {                 permsSet.add( menu.getResources() );             }         }         //将查到的权限和角色分别传入authorizationInfo中         authorizationInfo.setStringPermissions(permsSet);         authorizationInfo.setRoles(rolesSet);         log.info("--------------- 赋予角色和权限成功! ---------------");         return authorizationInfo;     } 

2、当用户权限发生改变时,需要重新退出登陆刷新权限。

不需要重新登陆实现权限刷新,参考博客:https://blog.csdn.net/qq_38225558/article/details/101616759

Top