色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

Springboot+mybatis-plus+注解實(shí)現(xiàn)數(shù)據(jù)權(quán)限隔離

瀏覽:13日期:2023-02-27 15:48:03
目錄1.創(chuàng)建注解2. 具體實(shí)現(xiàn)1.創(chuàng)建注解

當(dāng)此注解打在類上,不需要傳參,該類下所有查詢接口開啟數(shù)據(jù)隔離;打在方法上默認(rèn)開啟數(shù)據(jù)隔離,傳參為false則該方法關(guān)閉驗(yàn)證

/** * 數(shù)據(jù)權(quán)限驗(yàn)證注解 * @author xiaohua * @date 2021/6/23 */@Documented@Target({METHOD, ANNOTATION_TYPE, TYPE})@Retention(RUNTIME)public @interface DataPermission { /** * 是否要進(jìn)行數(shù)據(jù)權(quán)限隔離 */ boolean isPermi() default true;}2. 具體實(shí)現(xiàn)

@Component@Intercepts({@Signature(type = StatementHandler.class, method = 'prepare', args = {Connection.class, Integer.class})})public class DataPermissionInterceptor implements Interceptor { private static final Logger logger = LoggerFactory.getLogger(DataPermissionInterceptor.class); @Autowired private TokenService tokenService; //掃描的包路徑(根據(jù)自己的項(xiàng)目路徑來),這里是取的配置里的包路徑 @Value('${permission.package-path}') private String packagePath; private final static String DEPT_ID = 'dept_id'; private final static String USER_ID = 'create_user'; private static List<String> classNames; @Override public Object intercept(Invocation invocation) throws Throwable {try { LoginInfo user = tokenService.getLoginInfo(); if (user == null){return invocation.proceed(); } List<Long> deptIds = (List<Long>) Convert.toList(user.getDataScope()); if (deptIds == null){deptIds = new ArrayList<>(); } //反射掃包會(huì)比較慢,這里做了個(gè)懶加載 if (classNames == null) {synchronized (LazyInit.class){ if (classNames == null){//掃描指定包路徑下所有包含指定注解的類Set<Class<?>> classSet = ClassUtil.scanPackageByAnnotation(packagePath, DataPermission.class);if (classSet == null && classSet.size() == 0){ classNames = new ArrayList<>();} else { //取得類全名 classNames = classSet.stream().map(Class::getName).collect(Collectors.toList());} }} } // 拿到mybatis的一些對(duì)象 StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget()); MetaObject metaObject = SystemMetaObject.forObject(statementHandler); MappedStatement mappedStatement = (MappedStatement) metaObject.getValue('delegate.mappedStatement'); // mappedStatement.getId()為執(zhí)行的mapper方法的全路徑名,newId為執(zhí)行的mapper方法的類全名 String newId = mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf('.')); // 如果不是指定的方法,直接結(jié)束攔截 if (!classNames.contains(newId)) {return invocation.proceed(); } String newName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf('.') + 1, mappedStatement.getId().length()); //是否開啟數(shù)據(jù)權(quán)限 boolean isPermi = true; Class<?> clazz = Class.forName(newId); //遍歷方法 for (Method method : clazz.getDeclaredMethods()) {//方法是否含有DataPermission注解,如果含有注解則將數(shù)據(jù)結(jié)果過濾if (method.isAnnotationPresent(DataPermission.class) && newName.equals(method.getName())) { DataPermission dataPermission = method.getAnnotation(DataPermission.class); if (dataPermission != null) {//不驗(yàn)證if (!dataPermission.isPermi()) { isPermi = false;} else { //開啟驗(yàn)證 isPermi = true;} }} } if (isPermi){// 獲取到原始sql語句String sql = statementHandler.getBoundSql().getSql();// 解析并返回新的SQL語句,只處理查詢sqlif (mappedStatement.getSqlCommandType().toString().equals('SELECT')) { // String newSql = getNewSql(sql,deptIds,user.getUserId()); sql = getSql(sql,deptIds,user.getUserId());}// 修改sqlmetaObject.setValue('delegate.boundSql.sql', sql); } return invocation.proceed();} catch (Exception e){ logger.error('數(shù)據(jù)權(quán)限隔離異常:', e); return invocation.proceed();} } /** * 解析SQL語句,并返回新的SQL語句 * 注意,該方法使用了JSqlParser來操作SQL,該依賴包Mybatis-plus已經(jīng)集成了。如果要單獨(dú)使用,請(qǐng)先自行導(dǎo)入依賴 * * @param sql 原SQL * @return 新SQL */ private String getSql(String sql,List<Long> deptIds,Long userId) {try { String condition = ''; String permissionSql = '('; if (deptIds.size() > 0){for (Long deptId : deptIds) { if ('('.equals(permissionSql)){permissionSql = permissionSql + deptId; } else {permissionSql = permissionSql + ',' + deptId; }}permissionSql = permissionSql + ')';// 修改原語句condition = DEPT_ID +' in ' + permissionSql; } else {condition = USER_ID +' = ' + userId; } if (StringUtils.isBlank(condition)){return sql; } Select select = (Select)CCJSqlParserUtil.parse(sql); PlainSelect plainSelect = (PlainSelect)select.getSelectBody(); //取得原SQL的where條件 final Expression expression = plainSelect.getWhere(); //增加新的where條件 final Expression envCondition = CCJSqlParserUtil.parseCondExpression(condition); if (expression == null) {plainSelect.setWhere(envCondition); } else {AndExpression andExpression = new AndExpression(expression, envCondition);plainSelect.setWhere(andExpression); } return plainSelect.toString();} catch (JSQLParserException e) { logger.error('解析原SQL并構(gòu)建新SQL錯(cuò)誤:' + e); return sql;} }

到此這篇關(guān)于Springboot+mybatis-plus+注解實(shí)現(xiàn)數(shù)據(jù)權(quán)限隔離的文章就介紹到這了,更多相關(guān)Springboot+mybatis-plus+注解實(shí)現(xiàn)數(shù)據(jù)權(quán)限隔離內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 久久性久久性久久久爽 | 日韩欧美国产成人 | 美女被免费网站在线视频软件 | 久久99国产精品视频 | 特级一级全黄毛片免费 | 亚洲一区欧美二区 | 成人一a毛片免费视频 | 亚洲国产欧美日韩精品一区二区三区 | 国产精品亚洲高清一区二区 | 国产精品国色综合久久 | 免费国产成人午夜在线观看 | 亚洲美女高清aⅴ视频免费 亚洲美女黄色片 | 久久久久久久久久免观看 | 国产在线精品一区二区不卡 | 亚洲精品午夜国产va久久成人 | 欧美午夜免费观看福利片 | 国产理论视频 | 失禁h啪肉尿出来高h | 亚洲免费视频观看 | 性久久久久久久久久 | 91情侣高清精品国产 | 欧美888| 99视频精品全部 在线 | 久99re视频9在线观看 | 美女黄色免费在线观看 | 久艹视频在线观看 | 毛片视频免费观看 | 一本大道香蕉大vr在线吗视频 | 特黄特色一级特色大片中文 | 一级毛片在线看 | 欧美f | 深夜爽爽爽福利动态图 | 亚洲第一激情 | 成人在线免费网站 | 久久国产精品一国产精品 | 九九国产精品 | 久久国产精品一国产精品 | 午夜天堂视频 | 免费观看一级欧美大 | 黄色网址网站在线观看 | 久久久精品在线观看 |