package com.persagy.account.manage; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.google.common.collect.Lists; import com.persagy.account.pojo.dto.SaasAccount; import com.persagy.account.pojo.dto.SaasArea; import com.persagy.account.pojo.dto.SaasGroup; import com.persagy.account.service.ISaasAccountService; import com.persagy.account.service.ISaasGroupService; import com.persagy.common.constant.SaasCommonConstant; import com.persagy.common.enums.ResponseCode; import com.persagy.common.exception.BusinessException; import com.persagy.common.utils.StringUtil; import cn.hutool.core.util.BooleanUtil; import cn.hutool.crypto.digest.MD5; /** * @version * @description * @company persagy * @author zhangqiankun * @since 2021年3月18日: 上午10:20:22 */ @Component public class SaasAuthHandler { private static MD5 md5 = MD5.create(); @Autowired private ISaasGroupService saasGroupService; @Autowired private ISaasAccountService saasAccountService; @Autowired private SaasAreaProjectHandler saasAreaProjectHandler; @Autowired private RedisTemplate redisTemplate; /** * 验证此账号的集团权限 * * @param accountId * @param groupCode * @return * 权限鉴定通过时: * 有accountbelong 账号所属字段 * 若有返回集团编码,则此返回值必须作为代码向下执行的sql条件; * 若有返回accountType,需进行 SaasCommonConstant.STR_STATUS_2.equals(accountType) 账号类型的判断 */ public Map validAccountAuth(String accountId, String groupCode) { // 获取此账号对应的集团权限 SaasAccount account = this.saasAccountService.getOne(accountId, null, null); if (account == null) { throw new BusinessException("账号信息为空"); } // 添加数据访问控制,账号类型,0-所有集团项目,1-单集团所有项目,2-其他 String accountType = account.getAccountType(); // 1时,判断是否有权限 Map result = new HashMap(2); if (SaasCommonConstant.STR_STATUS_1.equals(accountType)) { String allowGroupCode = account.getGroupCode(); if (StringUtil.isNotBlank(groupCode) && !groupCode.equals(allowGroupCode)) { throw new BusinessException("账号无该集团的访问权限"); } groupCode = allowGroupCode; } result.put(SaasCommonConstant.GROUP_CODE, groupCode); result.put(SaasCommonConstant.ACCOUNT_TYPE, accountType); result.put(SaasCommonConstant.ACCOUNT_BELONG, account.getAccountBelong()); return result; } /** * 返回允许此账号访问的集团信息 * * @param accountId * @param groupCode * @return 允许此账号访问的集团信息 */ public List getAllowGroupList(String accountId, String groupCode) { // 获取此账号对应的集团权限 Map accountAuth = this.validAccountAuth(accountId, groupCode); groupCode = accountAuth.get(SaasCommonConstant.GROUP_CODE); String accountType = accountAuth.get(SaasCommonConstant.ACCOUNT_TYPE); return this.getAllowGroupList(accountId, groupCode, accountType); } /** * 返回允许此账号访问的集团信息 * * @param accountId * @param groupCode * @param accountType * @return 允许此账号访问的集团信息 */ public List getAllowGroupList(String accountId, String groupCode, String accountType) { List groups = null; if (SaasCommonConstant.STR_STATUS_2.equals(accountType)) { SaasGroup saasGroup = new SaasGroup(); saasGroup.setGroupCode(groupCode); saasGroup.setValid(SaasCommonConstant.STATUS_1); groups = this.saasGroupService.queryAllowGroupInfo(saasGroup, accountId); } else { LambdaQueryWrapper queryWrapper = new SaasGroup.Builder().createQueryWrapper().validEq(SaasCommonConstant.STATUS_1).builderQueryWrapper(); groups = this.saasGroupService.list(queryWrapper); } return groups == null ? Lists.newArrayList() : groups; } /** * 返回被允许访问的区域树 * * @param accountId * @param groupCode * @return 允许此账号访问的集团信息 */ public List getAllowAreaList(String accountId, String groupCode) { // 获取此账号对应的集团权限 Map accountAuth = this.validAccountAuth(accountId, groupCode); groupCode = accountAuth.get(SaasCommonConstant.GROUP_CODE); String accountType = accountAuth.get(SaasCommonConstant.ACCOUNT_TYPE); return this.getAllowAreaList(accountId, groupCode, accountType); } /** * 返回被允许访问的区域树 * * @param accountId * @param groupCode * @param accountType * @return */ public List getAllowAreaList(String accountId, String groupCode, String accountType) { List topList = this.saasAreaProjectHandler.getTopAreaList(groupCode); if (SaasCommonConstant.STR_STATUS_2.equals(accountType)) { // 其他类型时,需要根据权限表数据,去匹配区域树 this.saasAreaProjectHandler.queryAllowAreaTree(topList, accountId, groupCode); } else { this.saasAreaProjectHandler.querySaasAreaTree(topList, false); } return topList; } /** * 申请授权码,每次重新生成 * * @param clientId * @param redirectUrl * @param accountId * @param groupCode * @param appId * @return */ public String getCode(String clientId, String redirectUrl, String accountId, String groupCode, String appId) { // 验证客户端ID是否存在 Boolean member = this.redisTemplate.opsForSet().isMember(SaasCommonConstant.SAAS_CLIENT_ID_REDIS_KEY, clientId); if (!BooleanUtil.isTrue(member)) { throw new BusinessException(ResponseCode.A0001.getCode(), "非法客户端"); } // 如果redirectUrl存在,验证是否为可用值 if (!this.validRedirectUrl(clientId, redirectUrl)) { throw new BusinessException(ResponseCode.A0001.getCode(), "非法客户端"); } // 设置账号相关信息 this.redisTemplate.opsForHash().put(clientId, SaasCommonConstant.APP_ID_REDIS_HASH_KEY, appId); this.redisTemplate.opsForHash().put(clientId, SaasCommonConstant.ACCOUNT_ID_REDIS_HASH_KEY, accountId); this.redisTemplate.opsForHash().put(clientId, SaasCommonConstant.GROUP_CODE_REDIS_HASH_KEY, groupCode); // 生成新的授权码,并验证授权码是否已存在 JSONObject temp = new JSONObject(); temp.put("time", System.currentTimeMillis()); temp.put("redirectUrl", redirectUrl); temp.put("clientId", clientId); String code = md5.digestHex(temp.toJSONString()); this.redisTemplate.opsForHash().put(clientId, SaasCommonConstant.CODE_REDIS_HASH_KEY, code); return code; } /** * 验证redirectUrl的有效性,此方法默认空的redirectUrl,校验为true * * @param clientId * @param redirectUrl * @return */ public boolean validRedirectUrl(String clientId, String redirectUrl) { if (StringUtil.isBlank(redirectUrl)) { return true; } // 判断是否为内部客户端,内部不校验url Boolean inner = (Boolean)this.redisTemplate.opsForHash().get(clientId, SaasCommonConstant.INNER_CLIENT_REDIS_HASH_KEY); if (BooleanUtil.isTrue(inner)) { return true; } Object object = this.redisTemplate.opsForHash().get(clientId, SaasCommonConstant.REDIRECT_URL_REDIS_HASH_KEY); if(object == null) { return false; } String allowUrl = (String) object; if (StringUtil.isBlank(allowUrl)) { return false; } if (allowUrl.equals(allowUrl)) { return true; } return false; } }