diff --git a/Auth.java b/Auth.java new file mode 100644 index 0000000000000000000000000000000000000000..ce38d48cde0a36d54aead85856c9b4b23e31765a --- /dev/null +++ b/Auth.java @@ -0,0 +1,11 @@ +package com.huawei.ci.gateway.common; + + +import com.huawei.ci.gateway.model.UserContext; + +import java.io.IOException; + +public interface Auth { + UserContext auth(String au) throws IOException; + String getLoginUrl(); +} diff --git a/PublicKeyAuth.java b/PublicKeyAuth.java new file mode 100644 index 0000000000000000000000000000000000000000..59235b5d2716fd7c82365bf9d1991993aab35b9e --- /dev/null +++ b/PublicKeyAuth.java @@ -0,0 +1,129 @@ +package com.huawei.ci.gateway.common; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.huawei.ci.gateway.model.UserContext; +import org.apache.commons.lang.StringUtils; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + + +/** + * 普通的登录校验 + */ +public class PublicKeyAuth implements Auth { + private static final int FIVE_MINUTES = 300000; + private static final int TIME_OUT = 10000; + private static final String[] SIGHATURE_FIELDS = {"user", "nonce", "timestamp"}; + private static final PublicKeyAuth AUTH = new PublicKeyAuth(); + private static final String ACCOUNT_SERVICE_URL = "cse://account"; + public static PublicKeyAuth getInstance(){ + return AUTH; + } + + /** + * 通过签名拿用户登录信息 + */ + @Override + public UserContext auth(String au) throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + Map codeInfo = objectMapper.readValue(au, HashMap.class); + if (codeInfo == null) { + throw new SecurityException("403 auth failed"); + } + Map params = (Map) codeInfo.get("authorization"); + String userName = params.get("user").toString(); + String pk = params.get("pk").toString(); + + //解密签名,获得签名json对象 + String signature = codeInfo.get("signature").toString(); + String publicKey = getMatchedPk(userName, pk); + if (StringUtils.isEmpty(publicKey)) { + throw new SecurityException("user's matched pk dose not find."); + } + Map signatureParams = decoder(signature, publicKey); + if (signatureParams == null) { + throw new SecurityException("403 auth failed."); + } + //签名中信息必须一致 + for (String field : SIGHATURE_FIELDS) { + if (!params.get(field).equals(signatureParams.get(field))) { + throw new SecurityException("403 auth failed."); + } + } + + Long timestamp = (Long) params.get("timestamp"); + //签名不能超时 + if (System.currentTimeMillis() - timestamp > FIVE_MINUTES) { + throw new SecurityException("403 auth failed."); + } + return getUserContext(userName); + } + + @Override + public String getLoginUrl() { + return null; + } + + //获取签名对象 + private String getMatchedPk(String user, String pk) { + HttpClientBuilder clientBuilder = HttpClients.custom(); + CloseableHttpClient httpClient = clientBuilder.build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); + requestFactory.setConnectionRequestTimeout(TIME_OUT); + requestFactory.setConnectTimeout(TIME_OUT); + requestFactory.setReadTimeout(TIME_OUT); + requestFactory.setHttpClient(httpClient); +// RestTemplate restTemplate = RestTemplateBuilder.create(); +// restTemplate.setRequestFactory(requestFactory); +// String accountPKRestUrl = ACCOUNT_SERVICE_URL + "/users/" + user + "/pks"; +// ResponseEntity response = restTemplate.getForEntity(accountPKRestUrl, RestResponse.class); +// RestResponse restResponse = response.getBody(); +// if (restResponse == null) { +// return ""; +// } +// List> userPkMapList = (List>) restResponse.getData(); +// if (userPkMapList.stream().map(userPk -> userPk.get("pk").trim()) +// .anyMatch(value -> value.equals(pk.trim()))) { +// return pk; +// } + return ""; + } + + private UserContext getUserContext(String user) { + HttpClientBuilder clientBuilder = HttpClients.custom(); + CloseableHttpClient httpClient = clientBuilder.build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); + requestFactory.setConnectionRequestTimeout(TIME_OUT); + requestFactory.setConnectTimeout(TIME_OUT); + requestFactory.setReadTimeout(TIME_OUT); + requestFactory.setHttpClient(httpClient); +// RestTemplate restTemplate = RestTemplateBuilder.create(); +// restTemplate.setRequestFactory(requestFactory); +// String accountPKRestUrl = ACCOUNT_SERVICE_URL + "/users/" + user; +// ResponseEntity response = restTemplate.getForEntity(accountPKRestUrl, RestResponse.class); +// RestResponse restResponse = response.getBody(); +// if (restResponse == null) { +// throw new SecurityException(); +// } +// Map userMap = (Map) restResponse.getData(); + UserContext userContext = new UserContext(); +// userContext.setId(userMap.get("id")); +// userContext.setName(userMap.get("name")); +// userContext.getExtendInfo().put("account", userMap.get("account")); +// userContext.setType(UserContext.AuthType.PK); +// userContext.setRandomCsrfToken(); + return userContext; + } + + // todo 转码 + private Map decoder(String sigature, String publicKey) { + Map signatureParams = null; + return signatureParams; + } +} diff --git a/ResourcesInitializerUtil.java b/ResourcesInitializerUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..84f1bba528510bf97381833ab175e75146b71ef3 --- /dev/null +++ b/ResourcesInitializerUtil.java @@ -0,0 +1,145 @@ +package com.huawei.ci.portal.provider.utils; + +import com.huawei.ci.portal.provider.enums.assistanthelper.AssistantConstants; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.io.*; +import java.util.*; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; + +/** + * @Description: 资源文件初始化处理类 + * @ClassName: com.huawei.ci.portal.provider.utils + * @Author: hwx1123794/hexiangyun + * @DateTime: 2022/7/21 10:04 + * @Params: + **/ +@Data +@AllArgsConstructor +@Component +public class ResourcesInitializerUtil { + + private static final Logger logger = LoggerFactory.getLogger(ResourcesInitializerUtil.class); + + private static StringBuilder replaceAll; + + private static String encoding = AssistantConstants.ENCODING; + + private static String replaceStr = AssistantConstants.BE_REPLACE_STR; + + private static int replaceSize = AssistantConstants.BE_REPLACE_SIZE; + + private static String fileName = AssistantConstants.FILE_PATH; + + private static HashSet strings = new HashSet<>(100); + + private static Set allSensitiveWordSet = new HashSet<>(); + + private static Map afterDealingSensitiveWords = new HashMap<>(); + + + /** + * 文件 + * + * @param fileName 词库文件名(含后缀) + */ + public ResourcesInitializerUtil(String fileName) { + this.fileName = fileName; + } + + + /** + * 初始化敏感词库 + * + * @return + */ + protected Map InitializationWorkUtil() { + replaceAll = new StringBuilder(replaceSize); + for (int x = 0; x < replaceSize; x++) { + replaceAll.append(replaceStr); + } + InputStreamReader read = null; + BufferedReader bufferedReader = null; + ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); + // 读锁加锁 + reentrantReadWriteLock.readLock().lock(); + try { + logger.info("Init sensitive-words configuration start "); + read = new InputStreamReader(Objects.requireNonNull(ResourcesInitializerUtil.class.getClassLoader() + .getResourceAsStream(fileName)), encoding); + // 缓冲区大小 手动设置为80K + bufferedReader = new BufferedReader(read, 81920); + allSensitiveWordSet = bufferedReader.lines().collect(Collectors.toSet()); + // 构造属性 + afterDealingSensitiveWords = addSensitiveWords2HashConstruct(allSensitiveWordSet); + logger.info("Init sensitive-words configuration success "); + + } catch (IOException e) { + logger.error("read file failed"); + } finally { + try { + if (null != bufferedReader) + // 缓冲流关闭 + bufferedReader.close(); + } catch (IOException e) { + logger.error("shutdown Buffered streamline failed, caused by: " + e); + } + try { + if (null != read) + // IO流关闭 + read.close(); + } catch (IOException e) { + logger.error("shutdown IO streamline failed , caused by: " + e); + } + // 释放 + reentrantReadWriteLock.readLock().unlock(); + } + return afterDealingSensitiveWords; + } + + + /** + * DFA算法构造敏感词树形结构 (凡是相同字符开头的都在同一个HashMap + 树形结构 ) + * + * @param sensitiveWords 从文件中读取的敏感词集合 + * @return + */ + private HashMap addSensitiveWords2HashConstruct(Set sensitiveWords) { + // 关键字 整理成 Hash->树形 结构。 + HashMap sensitiveWordsMap = new HashMap(sensitiveWords.size()); + String currentWord = null; + Map childMap = null; + Map newWordMap = new HashMap<>(); + // 处理敏感词 + Iterator iterator = sensitiveWords.iterator(); + while (iterator.hasNext()) { + currentWord = iterator.next(); + childMap = sensitiveWordsMap; + // 关键字构造树形结构 + for (int i = 0; i < currentWord.length(); i++) { + char key = currentWord.charAt(i); + Object wordMap = childMap.get(key); + if (wordMap != null) { + childMap = (Map) wordMap; + } else { + newWordMap = new HashMap<>(); + // 添加标记位 + newWordMap.put("isEnd", "0"); + childMap.put(key, newWordMap); + childMap = newWordMap; + } + // 最后一位 + if (i == currentWord.length() - 1) { + childMap.put("isEnd", "1"); + } + } + } + return sensitiveWordsMap; + } +} diff --git a/RightManager.java b/RightManager.java new file mode 100644 index 0000000000000000000000000000000000000000..fa1332eaa8d13d03392502c91a2676c553af3802 --- /dev/null +++ b/RightManager.java @@ -0,0 +1,22 @@ +package com.huawei.ci.gateway.common; + +import com.huawei.ci.gateway.model.UserContext; +import com.netflix.config.DynamicPropertyFactory; +import io.vertx.core.http.HttpMethod; + +public class RightManager { + + private DynamicPropertyFactory propertyFactory=DynamicPropertyFactory.getInstance(); + + public static RightManager instance() { + return new RightManager(); + } + + /** + * todo 获取认证模式 + */ + public UserContext.AuthType getURLAuthType(String url, HttpMethod method){ + String model=propertyFactory.getStringProperty("ci.model","public").getValue(); + return UserContext.AuthType.PK; + } +}