Java如何實現(xiàn)http接口參數(shù)和返回值加密
參數(shù)和返回值得加密目的
為了保證接口不被人攔截下來惡意請求,保證程序的穩(wěn)定性,我們可以使用接口加密的方法來保證參數(shù)和返回值的保密性。
具體實現(xiàn)方式
因為本人是寫Java 的,所以這里就直接以Java代碼為例。思想都是一樣的,只是不同的語言都不同的實現(xiàn)方式。
大致思路
- 我們的參數(shù)和返回值只需要定義兩個參數(shù):ak,ct,ak存放堆成加密的秘鑰,ct存放加密之后的請求內容。
- 加密方式用到AES對稱加密和RSA非對稱加密,將請求參數(shù)使用AES加密,HTTP的POST請求和GET請求都可以將實際請求參數(shù)的格式定義成同一種格式(比如:JSON格式),便于后臺處理。AES加密使用的秘鑰用RSA加密。這樣我們就不需要操心參數(shù)加密的秘鑰是什么了,雙方都可以隨時更換。
- 使用過濾器獲取到請求的加密內容后,通過RSA解密將參數(shù)加密的秘鑰解析出來,然后再通過解析出來的秘鑰通過AES解密去獲取實際的請求內容。
注意:不同的請求方式獲取參數(shù)的方式不同,需要根據(jù)不同的請求方式去做不同的解析
代碼實現(xiàn)
1. 首先需要一個過濾器,因為我們要攔截請求參數(shù),和加密返回的數(shù)據(jù)。
因為并不是所有的接口都需要加密,過濾器不能想Spring攔截器那樣直接配置攔截和不攔截的類,所以定義了一個ALLOWED_PATHS 集合,用于過濾不需要加解密的請求。然后根據(jù)不同的請求方式去解析不同的請求內容,我這里只處理了get請求和post請求這兩種常用的請求方式。
package com.pay.filter; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** ?* 請求信息加解密 ?*/ @Log4j2 @Component @WebFilter(filterName = "EncryptionFilter", urlPatterns = {"/*"}) public class EncryptionFilter implements Filter { ? ? private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>( ? ? ? ? ? ? Arrays.asList("/pay/notify"))); ? ? @Override ? ? public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ? ? ? ? if(request instanceof HttpServletRequest) { ? ? ? ? ? ? HttpServletRequest hRequest = (HttpServletRequest) request; ? ? ? ? ? ? String servletPath = hRequest.getServletPath(); ? ? ? ? ? ? log.info("request_path:path="+servletPath); ? ? ? ? ? ? boolean allow = false; ? ? ? ? ? ? for (String allowedPath : ALLOWED_PATHS) { ? ? ? ? ? ? ? ? if(servletPath.contains(allowedPath)) { ? ? ? ? ? ? ? ? ? ? allow = true; ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? if(allow) { ? ? ? ? ? ? ? chain.doFilter(request, response); ? ? ? ? ? ? ? log.info("no Encryption"); ? ? ? ? ? ? ? return; ? ? ? ? ? ? } ? ? ? ? ? ? MyHttpServletResponseWrapper responseWrapper = new MyHttpServletResponseWrapper((HttpServletResponse) response); ? ? ? ? ? ? if(hRequest.getMethod().equalsIgnoreCase("post")) { ? ? ? ? ? ? ? ? MyHttpServletRequestWrapper requestWrapper = null; ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? requestWrapper = new MyHttpServletRequestWrapper(hRequest); ? ? ? ? ? ? ? ? } catch (Exception e) { ? ? ? ? ? ? ? ? ? ? request.getRequestDispatcher("404.html").forward(request,response); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? chain.doFilter(requestWrapper, responseWrapper); ? ? ? ? ? ? }else if(!hRequest.getMethod().equalsIgnoreCase("options")){ ? ? ? ? ? ? ? ? log.info("收到 potions請求"); ? ? ? ? ? ? } else { //其余默認get請求 ? ? ? ? ? ? ? ? ParameterRequestWrapper requestWrapper = null; ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? requestWrapper = new ParameterRequestWrapper(hRequest); ? ? ? ? ? ? ? ? } catch (Exception e) { ? ? ? ? ? ? ? ? ? ? request.getRequestDispatcher("404.html").forward(request,response); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? chain.doFilter(requestWrapper, responseWrapper); ? ? ? ? ? ? } ? ? ? ? ? ? String resp = responseWrapper.getTextContent(); //獲取接口返回內容 ? ? ? ? ? ? //加密處理返回 ? ? ? ? ? ? response.getOutputStream().write(HttpEncryptUtil.serverEncrypt(resp).getBytes(StandardCharsets.UTF_8)); ? ? ? ? } ? ? } }
2. 對于POST請求,定義一個解析request中參數(shù)的類 MyHttpServletRequestWrapper繼承HttpServletRequestWrapper ,去解析請求參數(shù)。
具體實現(xiàn)方式如下:
readBody:實際解析請求參數(shù)
package com.pay.filter; import com.alipay.api.internal.util.file.IOUtils; import com.pay.util.HttpEncryptUtil; import org.apache.commons.lang3.StringUtils; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { ? ? private String requestBody = null; ? ? public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException { ? ? ? ? super(request); ? ? ? ? requestBody = readBody(request); ? ? } ? ? @Override ? ? public BufferedReader getReader() { ? ? ? ? return new BufferedReader(new InputStreamReader(getInputStream())); ? ? } ? ? @Override ? ? public ServletInputStream getInputStream() { ? ? ? ? final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody.getBytes(StandardCharsets.UTF_8)); ? ? ? ? return new ServletInputStream() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public boolean isFinished() { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? ? ? @Override ? ? ? ? ? ? public boolean isReady() { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? ? ? @Override ? ? ? ? ? ? public void setReadListener(ReadListener readListener) { ? ? ? ? ? ? } ? ? ? ? ? ? @Override ? ? ? ? ? ? public int read() throws IOException { ? ? ? ? ? ? ? ? return bais.read(); ? ? ? ? ? ? } ? ? ? ? }; ? ? } ? ? private static String readBody(ServletRequest request) throws IOException { ? ? ? ? String param = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8); ? ? ? ? if(StringUtils.isNotBlank(param)) { ? ? ? ? ? ? //解密請求參數(shù) ? ? ? ? ? ? return HttpEncryptUtil.serverDecrypt(param); ? ? ? ? } ? ? ? ? return param; ? ? } }
3. 對于get請求,定義一個參數(shù)類ParameterRequestWrapper,繼承HttpServletRequestWrapper 去解析URL上的參數(shù)
具體方式如下:
重載構造方法獲取加密之后的參數(shù),去解析出來
ParameterRequestWrapper(HttpServletRequest request)
重寫getParameter和setParameter等獲取參數(shù)和設置參數(shù)的方法
package com.pay.filter; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.pay.util.HttpEncryptUtil; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.util.HashMap; import java.util.Map; public class ParameterRequestWrapper extends HttpServletRequestWrapper { ? ? private Map<String , String[]> params = new HashMap<String, String[]>(); ? ? @SuppressWarnings("unchecked") ? ? public ParameterRequestWrapper(HttpServletRequest request) { ? ? ? ? // 將request交給父類,以便于調用對應方法的時候,將其輸出,其實父親類的實現(xiàn)方式和第一種new的方式類似 ? ? ? ? super(request); ? ? ? ? //將參數(shù)表,賦予給當前的Map以便于持有request中的參數(shù) ? ? ? ? //解析 ? ? ? ? String ak = request.getParameter("ak"); ? ? ? ? String ct = request.getParameter("ct"); ? ? ? ? JSONObject jsonObject = new JSONObject(); ? ? ? ? jsonObject.put("ak",ak); ? ? ? ? jsonObject.put("ct",ct); ? ? ? ? String s = HttpEncryptUtil.serverDecrypt(jsonObject.toJSONString()); ? ? ? ? addAllParameters(JSON.parseObject(s)); ? ? } ? ? //重載一個構造方法 ? ? public ParameterRequestWrapper(HttpServletRequest request , Map<String , Object> extendParams) { ? ? ? ? this(request); ? ? ? ? addAllParameters(extendParams);//這里將擴展參數(shù)寫入?yún)?shù)表 ? ? } ? ? @Override ? ? public String getParameter(String name) {//重寫getParameter,代表參數(shù)從當前類中的map獲取 ? ? ? ? String[]values = params.get(name); ? ? ? ? if(values == null || values.length == 0) { ? ? ? ? ? ? return null; ? ? ? ? } ? ? ? ? return values[0]; ? ? } ? ? public String[] getParameterValues(String name) {//同上 ? ? ? ? return params.get(name); ? ? } ? ? public void addAllParameters(Map<String , Object>otherParams) {//增加多個參數(shù) ? ? ? ? for(Map.Entry<String , Object>entry : otherParams.entrySet()) { ? ? ? ? ? ? addParameter(entry.getKey() , entry.getValue()); ? ? ? ? } ? ? } ? ? public void addParameter(String name , Object value) {//增加參數(shù) ? ? ? ? if(value != null) { ? ? ? ? ? ? if(value instanceof String[]) { ? ? ? ? ? ? ? ? params.put(name , (String[])value); ? ? ? ? ? ? }else if(value instanceof String) { ? ? ? ? ? ? ? ? params.put(name , new String[] {(String)value}); ? ? ? ? ? ? }else { ? ? ? ? ? ? ? ? params.put(name , new String[] {String.valueOf(value)}); ? ? ? ? ? ? } ? ? ? ? } ? ? } }
注意:為了便于區(qū)分我才把獲取post請求內容和get請求內容的類寫成了兩個,其實可以嘗試著去將兩個解析類合成一個
4. 加解密工具類 HttpEncryptUtil ,和兩個網(wǎng)上百度的AESUtil,RSAUtil
package com.pay.util; import com.alibaba.fastjson.JSONObject; import com.pay.common.Constant; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.interfaces.RSAPublicKey; public class HttpEncryptUtil { ? ? //解密請求內容 ? ? public static String serverDecrypt(String content) { ? ? ? ? JSONObject result = JSONObject.parseObject(content); ? ? ? ? String encryptAesKeyStr = result.getString("ak"); ? ? ? ? String encryptContent = result.getString("ct"); ? ? ? ? //使用私鑰解密 獲取解密內容的AES密鑰 // ? ? ? ?encryptAesKeyStr = decodeBase64String(encryptAesKeyStr); //base64解碼 ? ? ? ? PrivateKey privateKey = RSAUtil.getPrivateKey(HTTP_PRIVATE_KEY); ? ? ? ? String aesKey = RSAUtil.decryptByPrivate(decodeBase64String(encryptAesKeyStr), privateKey); ? ? ? ? //使用解密出來的key解密content:使用AES ? ? ? ? return AESUtil.decryptAES(decodeBase64String(encryptContent), aesKey); ? ? } ? ? public static String serverDecryptByPublic(String content) { ? ? ? ? JSONObject result = JSONObject.parseObject(content); ? ? ? ? String encryptAesKeyStr = result.getString("ak"); ? ? ? ? String encryptContent = result.getString("ct"); ? ? ? ? //使用私鑰解密 獲取解密內容的AES密鑰 // ? ? ? ?encryptAesKeyStr = decodeBase64String(encryptAesKeyStr); //base64解碼 ? ? ? ? RSAPublicKey publicKey = RSAUtil.getPublicKey(HTTP_PUBLIC_KEY); ? ? ? ? String aesKey = RSAUtil.decryptByPublic(decodeBase64String(encryptAesKeyStr), publicKey); ? ? ? ? //使用解密出來的key解密content:使用AES ? ? ? ? return AESUtil.decryptAES(decodeBase64String(encryptContent), aesKey); ? ? } ? ? //加密返回內容 ? ? public static String serverEncrypt(String content) { ? ? ? ? String aesKey = HTTP_CONTENT_KEY; ? ? ? ? //使用私鑰加密AES的key ? ? ? ? PrivateKey privateKey = RSAUtil.getPrivateKey(HTTP_PRIVATE_KEY); ? ? ? ? String ak = RSAUtil.encryptByPrivate(aesKey.getBytes(StandardCharsets.UTF_8), privateKey); ? ? ? ? String ct = AESUtil.encryptAES(content, aesKey); ? ? ? ? JSONObject result = new JSONObject(); ? ? ? ? result.put("ak",encodeBase64String(ak)); ? ? ? ? result.put("ct",encodeBase64String(ct)); ? ? ? ? return result.toJSONString(); ? ? } ? ? public static String serverEncryptByPublic(String content) { ? ? ? ? String aesKey = HTTP_CONTENT_KEY; ? ? ? ? //使用公鑰鑰加密AES的key ? ? ? ? RSAPublicKey publicKey = RSAUtil.getPublicKey(HTTP_PUBLIC_KEY); ? ? ? ? String ak = RSAUtil.encryptByPublic(aesKey.getBytes(StandardCharsets.UTF_8), publicKey); ? ? ? ? String ct = AESUtil.encryptAES(content, aesKey); ? ? ? ? JSONObject result = new JSONObject(); ? ? ? ? result.put("ak",encodeBase64String(ak)); ? ? ? ? result.put("ct",encodeBase64String(ct)); ? ? ? ? return result.toJSONString(); ? ? } ? ? public static String encodeBase64String(String content) { ? ? ? ? if(StringUtils.isBlank(content)) { ? ? ? ? ? ? return null; ? ? ? ? } ? ? ? ? return Base64.encodeBase64String(content.getBytes(StandardCharsets.UTF_8)); ? ? } ? ? public static String decodeBase64String(String content) { ? ? ? ? if(StringUtils.isBlank(content)) { ? ? ? ? ? ? return null; ? ? ? ? } ? ? ? ? return new String(Base64.decodeBase64(content), StandardCharsets.UTF_8); ? ? } }
package com.pay.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public class AESUtil { ? ? public static final Charset CHARSET = StandardCharsets.UTF_8; ? ? public static final String ALGORITHMS_MD5 = "MD5"; ? ? public static final String SHA = "SHA1PRNG"; ? ? public static final String ALGORITHM = "AES"; ? ? /** ? ? ?* 加密 ? ? ?* ? ? ?* @param content ?需要加密的內容 ? ? ?* @param password 加密密碼 ? ? ?* @return ? ? ?*/ ? ? public static byte[] encrypt(String content, String password) { ? ? ? ? try { ? ? ? ? ? ? KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM); ? ? ? ? ? ? SecureRandom random = SecureRandom.getInstance(SHA); ? ? ? ? ? ? random.setSeed(password.getBytes()); ? ? ? ? ? ? kgen.init(128, random); ? ? ? ? ? ? SecretKey secretKey = kgen.generateKey(); ? ? ? ? ? ? byte[] enCodeFormat = secretKey.getEncoded(); ? ? ? ? ? ? SecretKeySpec key = new SecretKeySpec(enCodeFormat, ALGORITHM); ? ? ? ? ? ? Cipher cipher = Cipher.getInstance(ALGORITHM);// 創(chuàng)建密碼器 ? ? ? ? ? ? byte[] byteContent = content.getBytes(CHARSET); ? ? ? ? ? ? cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化 ? ? ? ? ? ? return cipher.doFinal(byteContent); // 加密 ? ? ? ? } catch (Exception e) { ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? /** ? ? ?* 解密 ? ? ?* ? ? ?* @param content ?待解密內容 ? ? ?* @param password 解密密鑰 ? ? ?* @return ? ? ?*/ ? ? public static byte[] decrypt(byte[] content, String password) { ? ? ? ? try { ? ? ? ? ? ? KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM); ? ? ? ? ? ? SecureRandom random = SecureRandom.getInstance(SHA); ? ? ? ? ? ? random.setSeed(password.getBytes()); ? ? ? ? ? ? kgen.init(128, random); ? ? ? ? ? ? SecretKey secretKey = kgen.generateKey(); ? ? ? ? ? ? byte[] enCodeFormat = secretKey.getEncoded(); ? ? ? ? ? ? SecretKeySpec key = new SecretKeySpec(enCodeFormat, ALGORITHM); ? ? ? ? ? ? Cipher cipher = Cipher.getInstance(ALGORITHM);// 創(chuàng)建密碼器 ? ? ? ? ? ? cipher.init(Cipher.DECRYPT_MODE, key);// 初始化 ? ? ? ? ? ? return cipher.doFinal(content); // 加密 ? ? ? ? } catch (Exception e) { ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? /** ? ? ?* 將二進制轉換成16進制 ? ? ?* ? ? ?* @param buf ? ? ?* @return ? ? ?*/ ? ? public static String parseByte2HexStr(byte buf[]) { ? ? ? ? StringBuffer sb = new StringBuffer(); ? ? ? ? for (int i = 0; i < buf.length; i++) { ? ? ? ? ? ? String hex = Integer.toHexString(buf[i] & 0xFF); ? ? ? ? ? ? if (hex.length() == 1) { ? ? ? ? ? ? ? ? hex = '0' + hex; ? ? ? ? ? ? } ? ? ? ? ? ? sb.append(hex.toUpperCase()); ? ? ? ? } ? ? ? ? return sb.toString(); ? ? } ? ? /** ? ? ?* 將16進制轉換為二進制 ? ? ?* ? ? ?* @param hexStr ? ? ?* @return ? ? ?*/ ? ? public static byte[] parseHexStr2Byte(String hexStr) { ? ? ? ? if (hexStr.length() < 1) ? ? ? ? ? ? return null; ? ? ? ? byte[] result = new byte[hexStr.length() / 2]; ? ? ? ? for (int i = 0; i < hexStr.length() / 2; i++) { ? ? ? ? ? ? int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); ? ? ? ? ? ? int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16); ? ? ? ? ? ? result[i] = (byte) (high * 16 + low); ? ? ? ? } ? ? ? ? return result; ? ? } ? ? private static byte[] doSign(String algorithms, String inputStr) throws NoSuchAlgorithmException { ? ? ? ? MessageDigest messageDigest = MessageDigest.getInstance(algorithms); ? ? ? ? messageDigest.update(inputStr.getBytes(CHARSET)); ? ? ? ? return messageDigest.digest(); ? ? } ? ? private static String signToHexStr(String algorithms, String inputStr) { ? ? ? ? try { ? ? ? ? ? ? return parseByte2HexStr(doSign(algorithms, inputStr)); ? ? ? ? } catch (NoSuchAlgorithmException e) { ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? return null; ? ? ? ? } ? ? } ? ? public static String sign(String key, String sourceStr) { ? ? ? ? String md5Str1 = signToHexStr(ALGORITHMS_MD5, sourceStr); ? ? ? ? String sourceStr2 = md5Str1 + key; ? ? ? ? return signToHexStr(ALGORITHMS_MD5, sourceStr2); ? ? } ? ? public static String toDecryptParam(String sourceStr, String password){ ? ? ? ? try { ? ? ? ? ? ? byte[] sourceByte = parseHexStr2Byte(sourceStr); ? ? ? ? ? ? byte[] bytes = decrypt(sourceByte, password); ? ? ? ? ? ? return new String(bytes,CHARSET); ? ? ? ? }catch (Exception e){ ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? } ? ? ? ? return ""; ? ? } ? ? public static String toEncryptResult(Object sourceStr, String password){ ? ? ? ? String parameterJson = JSONObject.toJSONString(sourceStr); ? ? ? ? byte[] encode = encrypt(parameterJson, password); ? ? ? ? return parseByte2HexStr(encode); ? ? } ? ? public static String encryptAES(String content, String password) { ? ? ? ? try { ? ? ? ? ? ? Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); ? ? ? ? ? ? byte[] byteContent = content.getBytes("utf-8"); ? ? ? ? ? ? cipher.init(1, getSecretKey(password)); ? ? ? ? ? ? byte[] result = cipher.doFinal(byteContent); ? ? ? ? ? ? return Base64.encodeBase64String(result); ? ? ? ? } catch (Exception var5) { ? ? ? ? ? ? return null; ? ? ? ? } ? ? } ? ? public static String decryptAES(String content, String password) { ? ? ? ? try { ? ? ? ? ? ? Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); ? ? ? ? ? ? cipher.init(2, getSecretKey(password)); ? ? ? ? ? ? byte[] result = cipher.doFinal(Base64.decodeBase64(content)); ? ? ? ? ? ? return new String(result, "utf-8"); ? ? ? ? } catch (Exception var4) { ? ? ? ? ? ? return null; ? ? ? ? } ? ? } ? ? private static SecretKeySpec getSecretKey(String password) { ? ? ? ? KeyGenerator kg = null; ? ? ? ? try { ? ? ? ? ? ? kg = KeyGenerator.getInstance("AES"); ? ? ? ? ? ? SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); ? ? ? ? ? ? random.setSeed(password.getBytes()); ? ? ? ? ? ? kg.init(128, random); ? ? ? ? ? ? SecretKey secretKey = kg.generateKey(); ? ? ? ? ? ? return new SecretKeySpec(secretKey.getEncoded(), "AES"); ? ? ? ? } catch (NoSuchAlgorithmException var4) { ? ? ? ? ? ? return null; ? ? ? ? } ? ? }
package com.pay.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.*; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.*; /** ?* RSA算法加密/解密工具類 ?*/ @Slf4j public class RSAUtil { ? ? /** 算法名稱 */ ? ? private static final String ALGORITHM = ?"RSA"; ? ? /** 默認密鑰大小 */ ? ? private static final int KEY_SIZE = 1024; ? ? /** 用來指定保存密鑰對的文件名和存儲的名稱 */ ? ? private static final String PUBLIC_KEY_NAME = "publicKey"; ? ? private static final String PRIVATE_KEY_NAME = "privateKey"; ? ? private static final String PUBLIC_FILENAME = "publicKey.properties"; ? ? private static final String PRIVATE_FILENAME = "privateKey.properties"; ? ? /** 密鑰對生成器 */ ? ? private static? ? ? KeyPairGenerator keyPairGenerator = null; ? ? private static KeyFactory keyFactory = null; ? ? /** 緩存的密鑰對 */ ? ? private static KeyPair keyPair = null; ? ? /** Base64 編碼/解碼器 JDK1.8 */ ? ? private static Base64.Decoder decoder = Base64.getDecoder(); ? ? private static Base64.Encoder encoder = Base64.getEncoder(); ? ? /** 初始化密鑰工廠 */ ? ? static{ ? ? ? ? try { ? ? ? ? ? ? keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM); ? ? ? ? ? ? keyFactory = KeyFactory.getInstance(ALGORITHM); ? ? ? ? } catch (NoSuchAlgorithmException e) { ? ? ? ? ? ? log.error("RSAUtil[ERROR]:e={}",e); ? ? ? ? } ? ? } ? ? /** 私有構造器 */ ? ? private RSAUtil(){} ? ? /** ? ? ?* 生成密鑰對 ? ? ?* 將密鑰分別用Base64編碼保存到#publicKey.properties#和#privateKey.properties#文件中 ? ? ?* 保存的默認名稱分別為publicKey和privateKey ? ? ?*/ ? ? public static synchronized Map<String, Object> generateKeyPair(){ ? ? ? ? try { ? ? ? ? ? ? keyPairGenerator.initialize(KEY_SIZE,new SecureRandom(UUID.randomUUID().toString().replaceAll("-","").getBytes())); ? ? ? ? ? ? keyPair = keyPairGenerator.generateKeyPair(); ? ? ? ? } catch (InvalidParameterException e){ ? ? ? ? ? ? log.error("KeyPairGenerator does not support a key length of " + KEY_SIZE + ".",e); ? ? ? ? } catch (NullPointerException e){ ? ? ? ? ? ? log.error("RSAUtil#key_pair_gen is null,can not generate KeyPairGenerator instance.",e); ? ? ? ? } ? ? ? ? RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic(); ? ? ? ? RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate(); ? ? ? ? String publicKeyString = encoder.encodeToString(rsaPublicKey.getEncoded()); ? ? ? ? String privateKeyString = encoder.encodeToString(rsaPrivateKey.getEncoded()); ? ? ? ? storeKey(publicKeyString,PUBLIC_KEY_NAME,PUBLIC_FILENAME); ? ? ? ? storeKey(privateKeyString,PRIVATE_KEY_NAME,PRIVATE_FILENAME); ? ? ? ? Map<String, Object> keyPair = new HashMap<>(); ? ? ? ? keyPair.put("public", publicKeyString); ? ? ? ? keyPair.put("private", privateKeyString); ? ? ? ? return keyPair; ? ? } ? ? /** ? ? ?* 將指定的密鑰字符串保存到文件中,如果找不到文件,就創(chuàng)建 ? ? ?* @param keyString 密鑰的Base64編碼字符串(值) ? ? ?* @param keyName ?保存在文件中的名稱(鍵) ? ? ?* @param fileName 目標文件名 ? ? ?*/ ? ? private static void storeKey(String keyString,String keyName,String fileName){ ? ? ? ? Properties properties = new Properties(); ? ? ? ? //存放密鑰的絕對地址 ? ? ? ? String path = null; ? ? ? ? try{ ? ? ? ? ? ? path = RSAUtil.class.getClassLoader().getResource(fileName).toString(); ? ? ? ? ? ? path = path.substring(path.indexOf(":") + 1); ? ? ? ? }catch (NullPointerException e){ ? ? ? ? ? ? //如果不存#fileName#就創(chuàng)建 ? ? ? ? ? ? log.warn("storeKey()# " + fileName + " is not exist.Begin to create this file."); ? ? ? ? ? ? String classPath = RSAUtil.class.getClassLoader().getResource("").toString(); ? ? ? ? ? ? String prefix = classPath.substring(classPath.indexOf(":") + 1); ? ? ? ? ? ? String suffix = fileName; ? ? ? ? ? ? File file = new File(prefix + suffix); ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? file.createNewFile(); ? ? ? ? ? ? ? ? path = file.getAbsolutePath(); ? ? ? ? ? ? } catch (IOException e1) { ? ? ? ? ? ? ? ? log.error(fileName +" create fail.",e1); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? try(OutputStream out = new FileOutputStream(path)){ ? ? ? ? ? ? properties.setProperty(keyName,keyString); ? ? ? ? ? ? properties.store(out,"There is " + keyName); ? ? ? ? } catch (FileNotFoundException e) { ? ? ? ? ? ? log.error("ModulusAndExponent.properties is not found.",e); ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? log.error("OutputStream output failed.",e); ? ? ? ? } ? ? } ? ? /** ? ? ?* 獲取密鑰字符串 ? ? ?* @param keyName 需要獲取的密鑰名 ? ? ?* @param fileName 密鑰所在文件 ? ? ?* @return Base64編碼的密鑰字符串 ? ? ?*/ ? ? private static String getKeyString(String keyName,String fileName){ ? ? ? ? if (RSAUtil.class.getClassLoader().getResource(fileName) == null){ ? ? ? ? ? ? log.warn("getKeyString()# " + fileName + " is not exist.Will run #generateKeyPair()# firstly."); ? ? ? ? ? ? generateKeyPair(); ? ? ? ? } ? ? ? ? try(InputStream in = RSAUtil.class.getClassLoader().getResource(fileName).openStream()){ ? ? ? ? ? ? Properties properties = new Properties(); ? ? ? ? ? ? properties.load(in); ? ? ? ? ? ? return properties.getProperty(keyName); ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? log.error("getKeyString()#" + e.getMessage(),e); ? ? ? ? } ? ? ? ? return ?null; ? ? } ? ? /** ? ? ?* 從文件獲取RSA公鑰 ? ? ?* @return RSA公鑰 ? ? ?* @throws InvalidKeySpecException ? ? ?*/ ? ? public static RSAPublicKey getPublicKey(){ ? ? ? ? try { ? ? ? ? ? ? byte[] keyBytes = decoder.decode(getKeyString(PUBLIC_KEY_NAME,PUBLIC_FILENAME)); ? ? ? ? ? ? X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); ? ? ? ? ? ? return (RSAPublicKey)keyFactory.generatePublic(x509EncodedKeySpec); ? ? ? ? }catch (InvalidKeySpecException e) { ? ? ? ? ? ? log.error("getPublicKey()#" + e.getMessage(),e); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? public static RSAPublicKey getPublicKey(String publicKeyString) { ? ? ? ? if(StringUtils.isBlank(publicKeyString)) { ? ? ? ? ? ? return null; ? ? ? ? } ? ? ? ? try { ? ? ? ? ? ? byte[] keyBytes = decoder.decode(publicKeyString); ? ? ? ? ? ? X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); ? ? ? ? ? ? return (RSAPublicKey)keyFactory.generatePublic(x509EncodedKeySpec); ? ? ? ? }catch (InvalidKeySpecException e) { ? ? ? ? ? ? log.error("getPublicKey()#" + e.getMessage(),e); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? /** ? ? ?* 從文件獲取RSA私鑰 ? ? ?* @return RSA私鑰 ? ? ?* @throws InvalidKeySpecException ? ? ?*/ ? ? public static RSAPrivateKey getPrivateKey(){ ? ? ? ? try { ? ? ? ? ? ? byte[] keyBytes = decoder.decode(getKeyString(PRIVATE_KEY_NAME,PRIVATE_FILENAME)); ? ? ? ? ? ? PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); ? ? ? ? ? ? return (RSAPrivateKey)keyFactory.generatePrivate(pkcs8EncodedKeySpec); ? ? ? ? } catch (InvalidKeySpecException e) { ? ? ? ? ? ? log.error("getPrivateKey()#" + e.getMessage(),e); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? public static RSAPrivateKey getPrivateKey(String privateKeyString) { ? ? ? ? if(StringUtils.isBlank(privateKeyString)) { ? ? ? ? ? ? return null; ? ? ? ? } ? ? ? ? try { ? ? ? ? ? ? byte[] keyBytes = decoder.decode(privateKeyString); ? ? ? ? ? ? PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); ? ? ? ? ? ? return (RSAPrivateKey)keyFactory.generatePrivate(pkcs8EncodedKeySpec); ? ? ? ? } catch (InvalidKeySpecException e) { ? ? ? ? ? ? log.error("getPrivateKey()#" + e.getMessage(),e); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? /** ? ? ?* RSA公鑰加密 ? ? ?* @param content 等待加密的數(shù)據(jù) ? ? ?* @param publicKey RSA 公鑰 if null then getPublicKey() ? ? ?* @return 加密后的密文(16進制的字符串) ? ? ?*/ ? ? public static String encryptByPublic(byte[] content,PublicKey publicKey){ ? ? ? ? if (publicKey == null){ ? ? ? ? ? ? publicKey = getPublicKey(); ? ? ? ? } ? ? ? ? try { ? ? ? ? ? ? Cipher cipher = Cipher.getInstance("RSA"); ? ? ? ? ? ? cipher.init(Cipher.ENCRYPT_MODE,publicKey); ? ? ? ? ? ? //該密鑰能夠加密的最大字節(jié)長度 ? ? ? ? ? ? int splitLength = ((RSAPublicKey)publicKey).getModulus().bitLength() / 8 -11; ? ? ? ? ? ? byte[][] arrays = splitBytes(content,splitLength); ? ? ? ? ? ? StringBuffer stringBuffer = new StringBuffer(); ? ? ? ? ? ? for (byte[] array : arrays){ ? ? ? ? ? ? ? ? stringBuffer.append(bytesToHexString(cipher.doFinal(array))); ? ? ? ? ? ? } ? ? ? ? ? ? return stringBuffer.toString(); ? ? ? ? } catch (NoSuchAlgorithmException e) { ? ? ? ? ? ? log.error("encrypt()#NoSuchAlgorithmException",e); ? ? ? ? } catch (NoSuchPaddingException e) { ? ? ? ? ? ? log.error("encrypt()#NoSuchPaddingException",e); ? ? ? ? } catch (InvalidKeyException e) { ? ? ? ? ? ? log.error("encrypt()#InvalidKeyException",e); ? ? ? ? } catch (BadPaddingException e) { ? ? ? ? ? ? log.error("encrypt()#BadPaddingException",e); ? ? ? ? } catch (IllegalBlockSizeException e) { ? ? ? ? ? ? log.error("encrypt()#IllegalBlockSizeException",e); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? /** ? ? ?* RSA私鑰加密 ? ? ?* @param content 等待加密的數(shù)據(jù) ? ? ?* @param privateKey RSA 私鑰 if null then getPrivateKey() ? ? ?* @return 加密后的密文(16進制的字符串) ? ? ?*/ ? ? public static String encryptByPrivate(byte[] content,PrivateKey privateKey){ ? ? ? ? if (privateKey == null){ ? ? ? ? ? ? privateKey = getPrivateKey(); ? ? ? ? } ? ? ? ? try { ? ? ? ? ? ? Cipher cipher = Cipher.getInstance("RSA"); ? ? ? ? ? ? cipher.init(Cipher.ENCRYPT_MODE,privateKey); ? ? ? ? ? ? //該密鑰能夠加密的最大字節(jié)長度 ? ? ? ? ? ? int splitLength = ((RSAPrivateKey)privateKey).getModulus().bitLength() / 8 -11; ? ? ? ? ? ? byte[][] arrays = splitBytes(content,splitLength); ? ? ? ? ? ? StringBuffer stringBuffer = new StringBuffer(); ? ? ? ? ? ? for(byte[] array : arrays){ ? ? ? ? ? ? ? ? stringBuffer.append(bytesToHexString(cipher.doFinal(array))); ? ? ? ? ? ? } ? ? ? ? ? ? return stringBuffer.toString(); ? ? ? ? } catch (NoSuchAlgorithmException e) { ? ? ? ? ? ? log.error("encrypt()#NoSuchAlgorithmException",e); ? ? ? ? } catch (NoSuchPaddingException e) { ? ? ? ? ? ? log.error("encrypt()#NoSuchPaddingException",e); ? ? ? ? } catch (InvalidKeyException e) { ? ? ? ? ? ? log.error("encrypt()#InvalidKeyException",e); ? ? ? ? } catch (BadPaddingException e) { ? ? ? ? ? ? log.error("encrypt()#BadPaddingException",e); ? ? ? ? } catch (IllegalBlockSizeException e) { ? ? ? ? ? ? log.error("encrypt()#IllegalBlockSizeException",e); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? /** ? ? ?* RSA私鑰解密 ? ? ?* @param content 等待解密的數(shù)據(jù) ? ? ?* @param privateKey RSA 私鑰 if null then getPrivateKey() ? ? ?* @return 解密后的明文 ? ? ?*/ ? ? public static String decryptByPrivate(String content,PrivateKey privateKey){ ? ? ? ? if (privateKey == null){ ? ? ? ? ? ? privateKey = getPrivateKey(); ? ? ? ? } ? ? ? ? try { ? ? ? ? ? ? Cipher cipher = Cipher.getInstance("RSA"); ? ? ? ? ? ? cipher.init(Cipher.DECRYPT_MODE,privateKey); ? ? ? ? ? ? //該密鑰能夠加密的最大字節(jié)長度 ? ? ? ? ? ? int splitLength = ((RSAPrivateKey)privateKey).getModulus().bitLength() / 8; ? ? ? ? ? ? byte[] contentBytes = hexStringToBytes(content); ? ? ? ? ? ? byte[][] arrays = splitBytes(contentBytes,splitLength); ? ? ? ? ? ? StringBuffer stringBuffer = new StringBuffer(); ? ? ? ? ? ? String sTemp = null; ? ? ? ? ? ? for (byte[] array : arrays){ ? ? ? ? ? ? ? ? stringBuffer.append(new String(cipher.doFinal(array))); ? ? ? ? ? ? } ? ? ? ? ? ? return stringBuffer.toString(); ? ? ? ? } catch (NoSuchAlgorithmException e) { ? ? ? ? ? ? log.error("encrypt()#NoSuchAlgorithmException",e); ? ? ? ? } catch (NoSuchPaddingException e) { ? ? ? ? ? ? log.error("encrypt()#NoSuchPaddingException",e); ? ? ? ? } catch (InvalidKeyException e) { ? ? ? ? ? ? log.error("encrypt()#InvalidKeyException",e); ? ? ? ? } catch (BadPaddingException e) { ? ? ? ? ? ? log.error("encrypt()#BadPaddingException",e); ? ? ? ? } catch (IllegalBlockSizeException e) { ? ? ? ? ? ? log.error("encrypt()#IllegalBlockSizeException",e); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? /** ? ? ?* RSA公鑰解密 ? ? ?* @param content 等待解密的數(shù)據(jù) ? ? ?* @param publicKey RSA 公鑰 if null then getPublicKey() ? ? ?* @return 解密后的明文 ? ? ?*/ ? ? public static String decryptByPublic(String content,PublicKey publicKey){ ? ? ? ? if (publicKey == null){ ? ? ? ? ? ? publicKey = getPublicKey(); ? ? ? ? } ? ? ? ? try { ? ? ? ? ? ? Cipher cipher = Cipher.getInstance("RSA"); ? ? ? ? ? ? cipher.init(Cipher.DECRYPT_MODE,publicKey); ? ? ? ? ? ? //該密鑰能夠加密的最大字節(jié)長度 ? ? ? ? ? ? int splitLength = ((RSAPublicKey)publicKey).getModulus().bitLength() / 8; ? ? ? ? ? ? byte[] contentBytes = hexStringToBytes(content); ? ? ? ? ? ? byte[][] arrays = splitBytes(contentBytes,splitLength); ? ? ? ? ? ? StringBuffer stringBuffer = new StringBuffer(); ? ? ? ? ? ? String sTemp = null; ? ? ? ? ? ? for (byte[] array : arrays){ ? ? ? ? ? ? ? ? stringBuffer.append(new String(cipher.doFinal(array))); ? ? ? ? ? ? } ? ? ? ? ? ? return stringBuffer.toString(); ? ? ? ? } catch (NoSuchAlgorithmException e) { ? ? ? ? ? ? log.error("encrypt()#NoSuchAlgorithmException",e); ? ? ? ? } catch (NoSuchPaddingException e) { ? ? ? ? ? ? log.error("encrypt()#NoSuchPaddingException",e); ? ? ? ? } catch (InvalidKeyException e) { ? ? ? ? ? ? log.error("encrypt()#InvalidKeyException",e); ? ? ? ? } catch (BadPaddingException e) { ? ? ? ? ? ? log.error("encrypt()#BadPaddingException",e); ? ? ? ? } catch (IllegalBlockSizeException e) { ? ? ? ? ? ? log.error("encrypt()#IllegalBlockSizeException",e); ? ? ? ? } ? ? ? ? return null; ? ? } ? ? /** ? ? ?* 根據(jù)限定的每組字節(jié)長度,將字節(jié)數(shù)組分組 ? ? ?* @param bytes 等待分組的字節(jié)組 ? ? ?* @param splitLength 每組長度 ? ? ?* @return 分組后的字節(jié)組 ? ? ?*/ ? ? public static byte[][] splitBytes(byte[] bytes,int splitLength){ ? ? ? ? //bytes與splitLength的余數(shù) ? ? ? ? int remainder = bytes.length % splitLength; ? ? ? ? //數(shù)據(jù)拆分后的組數(shù),余數(shù)不為0時加1 ? ? ? ? int quotient = remainder != 0 ? bytes.length / splitLength + 1:bytes.length / splitLength; ? ? ? ? byte[][] arrays = new byte[quotient][]; ? ? ? ? byte[] array = null; ? ? ? ? for (int i =0;i<quotient;i++){ ? ? ? ? ? ? //如果是最后一組(quotient-1),同時余數(shù)不等于0,就將最后一組設置為remainder的長度 ? ? ? ? ? ? if (i == quotient -1 && remainder != 0){ ? ? ? ? ? ? ? ? array = new byte[remainder]; ? ? ? ? ? ? ? ? System.arraycopy(bytes,i * splitLength,array,0,remainder); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? array = new byte[splitLength]; ? ? ? ? ? ? ? ? System.arraycopy(bytes,i*splitLength,array,0,splitLength); ? ? ? ? ? ? } ? ? ? ? ? ? arrays[i] = array; ? ? ? ? } ? ? ? ? return arrays; ? ? } ? ? /** ? ? ?* 將字節(jié)數(shù)組轉換成16進制字符串 ? ? ?* @param bytes 即將轉換的數(shù)據(jù) ? ? ?* @return 16進制字符串 ? ? ?*/ ? ? public static String bytesToHexString(byte[] bytes){ ? ? ? ? StringBuffer sb = new StringBuffer(bytes.length); ? ? ? ? String temp = null; ? ? ? ? for (int i = 0;i< bytes.length;i++){ ? ? ? ? ? ? temp = Integer.toHexString(0xFF & bytes[i]); ? ? ? ? ? ? if(temp.length() <2){ ? ? ? ? ? ? ? ? sb.append(0); ? ? ? ? ? ? } ? ? ? ? ? ? sb.append(temp); ? ? ? ? } ? ? ? ? return sb.toString(); ? ? } ? ? /** ? ? ?* 將16進制字符串轉換成字節(jié)數(shù)組 ? ? ?* @param hex 16進制字符串 ? ? ?* @return byte[] ? ? ?*/ ? ? public static byte[] hexStringToBytes(String hex){ ? ? ? ? int len = (hex.length() / 2); ? ? ? ? hex = hex.toUpperCase(); ? ? ? ? byte[] result = new byte[len]; ? ? ? ? char[] chars = hex.toCharArray(); ? ? ? ? for (int i= 0;i<len;i++){ ? ? ? ? ? ? int pos = i * 2; ? ? ? ? ? ? result[i] = (byte)(toByte(chars[pos]) << 4 | toByte(chars[pos + 1])); ? ? ? ? } ? ? ? ? return result; ? ? } ? ? /** ? ? ?* 將char轉換為byte ? ? ?* @param c char ? ? ?* @return byte ? ? ?*/ ? ? private static byte toByte(char c){ ? ? ? ? return (byte)"0123456789ABCDEF".indexOf(c); ? ? }
身份檢驗
除了參數(shù)加密之外,我們還可以做一個簡單的身份校驗。這里就需要使用到Spring的攔截器了。
可以在header中放一個身份token,攔截器里面校驗
具體實現(xiàn):
一個攔截器 TokenInterceptor.java 和配置類 WebConfig.java
package com.pay.filter; import com.alibaba.fastjson.JSONObject; import com.pay.common.ErrorCode; import com.pay.common.GlobalEnums; import com.pay.entity.SourceConfig; import com.pay.service.SourceConfigService; import com.pay.util.RedisUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component @Slf4j public class TokenInterceptor implements HandlerInterceptor { ? ? @Autowired ? ? private SourceConfigService sourceConfigService; ? ? @Override ? ? public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception { ? ? ? ? String token = httpServletRequest.getHeader("token"); ? ? ? ? httpServletResponse.setContentType("text/html;charset=utf-8"); ? ? ? ? httpServletResponse.setCharacterEncoding("utf-8"); ? ? ? ? ServletOutputStream outputStream = httpServletResponse.getOutputStream(); ? ? ? ? JSONObject jsonObject =new JSONObject(); ? ? ? ? if(StringUtils.isBlank(token)) { ? ? ? ? ? ? jsonObject.put("code", ErrorCode.Ax000014.getCode()); ? ? ? ? ? ? jsonObject.put("message", ErrorCode.Ax000014.getMessage()); ? ? ? ? ? ? outputStream.write(jsonObject.toJSONString().getBytes()); ? ? ? ? ? ? return false; ? ? ? ? } ? ? ? ? SourceConfig sourceConfig = sourceConfigService.selectBySource(token); ? ? ? ? if(sourceConfig == null) { ? ? ? ? ? ? jsonObject.put("code", ErrorCode.Ax000014.getCode()); ? ? ? ? ? ? jsonObject.put("message", ErrorCode.Ax000014.getMessage()); ? ? ? ? ? ? outputStream.write(jsonObject.toJSONString().getBytes()); ? ? ? ? ? ? return false; ? ? ? ? } ? ? ? ? if(sourceConfig.getStatus().equals(GlobalEnums.EnableEnum.FALSE.getEnable())) { ? ? ? ? ? ? jsonObject.put("code", ErrorCode.Ax000014.getCode()); ? ? ? ? ? ? jsonObject.put("message", ErrorCode.Ax000014.getMessage()); ? ? ? ? ? ? outputStream.write(jsonObject.toJSONString().getBytes()); ? ? ? ? ? ? return false; ? ? ? ? } ? ? ? ? return true; ? ? } ? ? @Override ? ? public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { ? ? } ? ? @Override ? ? public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) ? ? ? ? ? ? throws Exception { ? ? ? ? RequestTokenHolder.remove(); ? ? } }
package com.pay.config; import com.pay.filter.TokenInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.annotation.Resource; @Configuration public class WebConfig implements WebMvcConfigurer { ? ? @Override ? ? public void addViewControllers(ViewControllerRegistry registry) { ? ? } ? ? @Resource ? ? private TokenInterceptor tokenInterceptor; ? ? /** ? ? ?* 這個方法用來注冊攔截器,我們自己寫好的攔截器需要通過這里添加注冊才能生效 ? ? ?* ? ? ?* @param registry "" ? ? ?*/ ? ? @Override ? ? public void addInterceptors(InterceptorRegistry registry) { ? ? ? ? registry.addInterceptor(tokenInterceptor) ? ? ? ? ? ? ? ? .addPathPatterns("/**") ? ? ? ? ? ? ? ? .excludePathPatterns( ? ? ? ? ? ? ? ? ? ? ? ? "/pay/notify/**"http://登錄接口 ? ? ? ? ? ? ? ? ) ? ? ? ? ? ? ? ? // 過濾swagger ? ? ? ? ? ? ? ? .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"); ? ? } }
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Java編程中使用JDBC API連接數(shù)據(jù)庫和創(chuàng)建程序的方法
這篇文章主要介紹了Java編程中使用JDBC API連接數(shù)據(jù)庫和創(chuàng)建程序的基本教程,JDBC是一種用于執(zhí)行SQL語句的Java API,可以為多種關系數(shù)據(jù)庫提供統(tǒng)一訪問需要的朋友可以參考下2015-12-12使用Spring?Boot+gRPC構建微服務并部署的案例詳解
這篇文章主要介紹了使用Spring?Boot+gRPC構建微服務并部署,Spring Cloud僅僅是一個開發(fā)框架,沒有實現(xiàn)微服務所必須的服務調度、資源分配等功能,這些需求要借助Kubernetes等平臺來完成,本文給大家介紹的非常詳細,需要的朋友參考下吧2022-06-06