From 098d3347a0df808908aab8c554cd7c4febc5e6d9 Mon Sep 17 00:00:00 2001 From: 疯狂的狮子Li <15040126243@163.com> Date: 星期一, 26 八月 2024 11:43:59 +0800 Subject: [PATCH] !577 发布 5.2.2 正式版 安全性提升 Merge pull request !577 from 疯狂的狮子Li/dev --- ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java | 71 +++++++++++++++++++++++++++++++---- 1 files changed, 62 insertions(+), 9 deletions(-) diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java index 7d7fd84..5ac74c3 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java @@ -68,13 +68,27 @@ */ private final BeanResolver beanResolver = new BeanFactoryResolver(SpringUtils.getBeanFactory()); + /** + * 鏋勯�犳柟娉曪紝鎵弿鎸囧畾鍖呬笅鐨� Mapper 绫诲苟鍒濆鍖栫紦瀛� + * + * @param mapperPackage Mapper 绫绘墍鍦ㄧ殑鍖呰矾寰� + */ public PlusDataPermissionHandler(String mapperPackage) { scanMapperClasses(mapperPackage); } - + /** + * 鑾峰彇鏁版嵁杩囨护鏉′欢鐨� SQL 鐗囨 + * + * @param where 鍘熷鐨勬煡璇㈡潯浠惰〃杈惧紡 + * @param mappedStatementId Mapper 鏂规硶鐨� ID + * @param isSelect 鏄惁涓烘煡璇㈣鍙� + * @return 鏁版嵁杩囨护鏉′欢鐨� SQL 鐗囨 + */ public Expression getSqlSegment(Expression where, String mappedStatementId, boolean isSelect) { + // 鑾峰彇鏁版嵁鏉冮檺閰嶇疆 DataPermission dataPermission = getDataPermission(mappedStatementId); + // 鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛淇℃伅 LoginUser currentUser = DataPermissionHelper.getVariable("user"); if (ObjectUtil.isNull(currentUser)) { currentUser = LoginHelper.getLoginUser(); @@ -84,7 +98,8 @@ if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) { return where; } - String dataFilterSql = buildDataFilter(dataPermission.value(), isSelect); + // 鏋勯�犳暟鎹繃婊ゆ潯浠剁殑 SQL 鐗囨 + String dataFilterSql = buildDataFilter(dataPermission, isSelect); if (StringUtils.isBlank(dataFilterSql)) { return where; } @@ -103,11 +118,19 @@ } /** - * 鏋勯�犳暟鎹繃婊ql + * 鏋勫缓鏁版嵁杩囨护鏉′欢鐨� SQL 璇彞 + * + * @param dataPermission 鏁版嵁鏉冮檺娉ㄨВ + * @param isSelect 鏍囧織褰撳墠鎿嶄綔鏄惁涓烘煡璇㈡搷浣滐紝鏌ヨ鎿嶄綔鍜屾洿鏂版垨鍒犻櫎鎿嶄綔鍦ㄥ鐞嗚繃婊ゆ潯浠舵椂浼氭湁涓嶅悓鐨勫鐞嗘柟寮� + * @return 鏋勫缓鐨勬暟鎹繃婊ゆ潯浠剁殑 SQL 璇彞 + * @throws ServiceException 濡傛灉瑙掕壊鐨勬暟鎹寖鍥村紓甯告垨鑰� key 涓� value 鐨勯暱搴︿笉鍖归厤锛屽垯鎶涘嚭 ServiceException 寮傚父 */ - private String buildDataFilter(DataColumn[] dataColumns, boolean isSelect) { + private String buildDataFilter(DataPermission dataPermission, boolean isSelect) { // 鏇存柊鎴栧垹闄ら渶婊¤冻鎵�鏈夋潯浠� String joinStr = isSelect ? " OR " : " AND "; + if (StringUtils.isNotBlank(dataPermission.joinStr())) { + joinStr = " " + dataPermission.joinStr() + " "; + } LoginUser user = DataPermissionHelper.getVariable("user"); StandardEvaluationContext context = new StandardEvaluationContext(); context.setBeanResolver(beanResolver); @@ -125,7 +148,7 @@ return ""; } boolean isSuccess = false; - for (DataColumn dataColumn : dataColumns) { + for (DataColumn dataColumn : dataPermission.value()) { if (dataColumn.key().length != dataColumn.value().length) { throw new ServiceException("瑙掕壊鏁版嵁鑼冨洿寮傚父 => key涓巚alue闀垮害涓嶅尮閰�"); } @@ -133,6 +156,13 @@ if (!StringUtils.containsAny(type.getSqlTemplate(), Arrays.stream(dataColumn.key()).map(key -> "#" + key).toArray(String[]::new) )) { + continue; + } + // 鍖呭惈鏉冮檺鏍囪瘑绗� 杩欑洿鎺ヨ烦杩� + if (StringUtils.isNotBlank(dataColumn.permission()) && + CollUtil.contains(user.getMenuPermission(), dataColumn.permission()) + ) { + isSuccess = true; continue; } // 璁剧疆娉ㄨВ鍙橀噺 key 涓鸿〃杈惧紡鍙橀噺 value 涓哄彉閲忓�� @@ -159,20 +189,29 @@ } /** - * 閫氳繃 mapperPackage 璁剧疆鐨勬壂鎻忓寘 鎵弿缂撳瓨鏈夋敞瑙g殑鏂规硶涓庣被 + * 鎵弿鎸囧畾鍖呬笅鐨� Mapper 绫伙紝骞舵煡鎵惧叾涓甫鏈夌壒瀹氭敞瑙g殑鏂规硶鎴栫被 + * + * @param mapperPackage Mapper 绫绘墍鍦ㄧ殑鍖呰矾寰� */ private void scanMapperClasses(String mapperPackage) { + // 鍒涘缓璧勬簮瑙f瀽鍣ㄥ拰鍏冩暟鎹鍙栧伐鍘� PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory(); + // 灏� Mapper 鍖呰矾寰勬寜鍒嗛殧绗︽媶鍒嗕负鏁扮粍 String[] packagePatternArray = StringUtils.splitPreserveAllTokens(mapperPackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); String classpath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX; try { for (String packagePattern : packagePatternArray) { + // 灏嗗寘璺緞杞崲涓鸿祫婧愯矾寰� String path = ClassUtils.convertClassNameToResourcePath(packagePattern); + // 鑾峰彇鎸囧畾璺緞涓嬬殑鎵�鏈� .class 鏂囦欢璧勬簮 Resource[] resources = resolver.getResources(classpath + path + "/*.class"); for (Resource resource : resources) { + // 鑾峰彇璧勬簮鐨勭被鍏冩暟鎹� ClassMetadata classMetadata = factory.getMetadataReader(resource).getClassMetadata(); + // 鑾峰彇璧勬簮瀵瑰簲鐨勭被瀵硅薄 Class<?> clazz = Resources.classForName(classMetadata.getClassName()); + // 鏌ユ壘绫讳腑鐨勭壒瀹氭敞瑙� findAnnotation(clazz); } } @@ -181,9 +220,13 @@ } } + /** + * 鍦ㄦ寚瀹氱殑绫讳腑鏌ユ壘鐗瑰畾鐨勬敞瑙� DataPermission锛屽苟灏嗗甫鏈夎繖涓敞瑙g殑鏂规硶鎴栫被瀛樺偍鍒� dataPermissionCacheMap 涓� + * + * @param clazz 瑕佹煡鎵剧殑绫� + */ private void findAnnotation(Class<?> clazz) { DataPermission dataPermission; - // 鑾峰彇鏂规硶娉ㄨВ for (Method method : clazz.getMethods()) { if (method.isDefault() || method.isVarArgs()) { continue; @@ -194,17 +237,24 @@ dataPermissionCacheMap.put(mappedStatementId, dataPermission); } } - // 鑾峰彇绫绘敞瑙� if (AnnotationUtil.hasAnnotation(clazz, DataPermission.class)) { dataPermission = AnnotationUtil.getAnnotation(clazz, DataPermission.class); dataPermissionCacheMap.put(clazz.getName(), dataPermission); } } + /** + * 鏍规嵁鏄犲皠璇彞 ID 鎴栫被鍚嶈幏鍙栧搴旂殑 DataPermission 娉ㄨВ瀵硅薄 + * + * @param mapperId 鏄犲皠璇彞 ID + * @return DataPermission 娉ㄨВ瀵硅薄锛屽鏋滀笉瀛樺湪鍒欒繑鍥� null + */ public DataPermission getDataPermission(String mapperId) { + // 妫�鏌ョ紦瀛樹腑鏄惁鍖呭惈鏄犲皠璇彞 ID 瀵瑰簲鐨� DataPermission 娉ㄨВ瀵硅薄 if (dataPermissionCacheMap.containsKey(mapperId)) { return dataPermissionCacheMap.get(mapperId); } + // 濡傛灉缂撳瓨涓笉鍖呭惈鏄犲皠璇彞 ID 瀵瑰簲鐨� DataPermission 娉ㄨВ瀵硅薄锛屽垯灏濊瘯浣跨敤绫诲悕浣滀负閿煡鎵� String clazzName = mapperId.substring(0, mapperId.lastIndexOf(".")); if (dataPermissionCacheMap.containsKey(clazzName)) { return dataPermissionCacheMap.get(clazzName); @@ -213,7 +263,10 @@ } /** - * 鏄惁鏃犳晥 + * 妫�鏌ョ粰瀹氱殑鏄犲皠璇彞 ID 鏄惁鏈夋晥锛屽嵆鏄惁鑳藉鎵惧埌瀵瑰簲鐨� DataPermission 娉ㄨВ瀵硅薄 + * + * @param mapperId 鏄犲皠璇彞 ID + * @return 濡傛灉鎵惧埌瀵瑰簲鐨� DataPermission 娉ㄨВ瀵硅薄锛屽垯杩斿洖 false锛涘惁鍒欒繑鍥� true */ public boolean invalid(String mapperId) { return getDataPermission(mapperId) == null; -- Gitblit v1.9.3