Spring设计安全的Restful接口
2017-08-28 11:29
405 查看
设计安全的Restful接口:无用户交互状态的接口安全设计。我们需要实现UR拦截请求拦截,接口接入授权验证和请求验重。本文中不涉及任何用户校验。
2.接入授权验证:验证请求头Token;
3.请求验重:验证请求序列Sequence;
接口设计文档请参考:WMS系统对外开放接口设计文档-V.1.0.docx
注:文档禁用于商业用途!
view plain
copyprint?
package com.wlyd.fmcgwms.util.security;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.wlyd.fmcgwms.util.Log;
import com.wlyd.fmcgwms.util.SAASTokenManager;
import com.wlyd.fmcgwms.util.StaticProperty;
import com.wlyd.fmcgwms.util.api.RSAUtils;
import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;
import com.wlyd.fmcgwms.util.sysinit.InitSysProperties;
/**
* 接口安全过滤器
*
* @package com.wlyd.fmcgwms.util.security.SecurityFilter
* @date 2017年3月15日 下午1:57:18
* @author pengjunlin
* @comment
* @update
*/
public class SecurityFilter implements Filter {
private static String API_ISENABLE ;// WMS是否开通对外接口
private static String API_PALTFORM;// WMS开放的平台编码
private static String API_MEMBERCODE;//WMS开放的服务商编码
private static String publicKey;// 公钥
private static String privateKey;// 私钥
@Override
public void destroy() {
// TODO Auto-generated method stub
}
/**
* 验证配置是否规范
*
* @MethodName: isConfiged
* @Description:
* @param platformCode
* @param memberCode
* @return
* @throws
*/
private boolean isConfiged(String platformCode,String memberCode){
if(API_ISENABLE==null||!API_ISENABLE.equals("true")){
return false;
}
if(API_PALTFORM==null||platformCode==null||!platformCode.equals(API_PALTFORM)){
return false;
}
if (API_MEMBERCODE==null||memberCode == null||! memberCode.equals(API_MEMBERCODE)) {
return false;
}
return true;
}
/**
* 验证token是否有效
*
* @MethodName: validateToken
* @Description:
* @param token
* @return
* @throws
*/
private boolean validateToken(String token){
if(token==null||token.equals("")){
return false;
}
String params[]=SAASTokenManager.decryptToken(privateKey, token, "&");
if(params==null||params.length<3){
return false;
}
long now=System.currentTimeMillis();
// Token超时验证20s
long seconds=(now-Long.valueOf(params[2]))/1000;
if(!API_PALTFORM.equals(params[0])||!API_MEMBERCODE.equals(params[1])||seconds>20){
return false;
}
return true;
}
/**
* 验证请求是否重复
*
* @MethodName: validateSequece
* @Description:
* @param sequence
* @return
* @throws
*/
public boolean validateSequece(String sequence){
if(sequence==null||sequence.equals("")){
return false;
}
String requestSequence=(String) EhcacheUtil.get(StaticProperty.REQUESTCACHE, sequence);
// 请求序列相同验证失败
if(requestSequence!=null&&sequence.equals(requestSequence)){
return false;
}
return true;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
PrintWriter out = null;
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String platformCode = req.getHeader("PlatformCode");
String&nb
1d25b
sp;memberCode = req.getHeader("MemberCode");
String token = req.getHeader("Token");
String sequence = req.getHeader("Sequence");
//String path = req.getServletPath();
try {
byte [] bytes=SAASTokenManager.generateBytesToken(publicKey, platformCode, memberCode,"&");
token = RSAUtils.bytesToString(bytes);
} catch (Exception e1) {
e1.printStackTrace();
}
// 验证接口是否配置正确
if(!isConfiged(platformCode, memberCode)){
JSONObject json = new JSONObject();
json.put("IsSuccess", "false");
json.put("OperationDesc", "API parameters are not configed right! ");
json.put("ResultCode", ResultCode.OPEN_API_CONFIG_ERROR);
try {
out = res.getWriter();
out.write(json.toJSONString());
} catch (Exception e) {
e.printStackTrace();
}
return;
}
// 验证Token是否合法
if(!validateToken(token)){
JSONObject json = new JSONObject();
json.put("IsSuccess", "false");
json.put("OperationDesc", "Unauthorized:Token is invalid!");
json.put("ResultCode", ResultCode.OPEN_API_TOKEN_INVALID);
try {
out = res.getWriter();
out.write(json.toJSONString());
} catch (Exception e) {
e.printStackTrace();
}
return;
}
// 验证Sequence是否合法
if(!validateSequece(sequence)){
JSONObject json = new JSONObject();
json.put("IsSuccess", "false");
json.put("OperationDesc", "Refused:request API too frequently!");
json.put("ResultCode", ResultCode.OPEN_API_REQUEST_REQUENTLY);
try {
out = res.getWriter();
out.write(json.toJSONString());
} catch (Exception e) {
e.printStackTrace();
}
return;
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。START!");
API_ISENABLE = InitSysProperties.getLowerCaseFromEhcache(StaticProperty.WMS_OPEN_API_ISENABLE);
API_PALTFORM = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_PLATFORM);
API_MEMBERCODE = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_MEMBERCODE);
publicKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PUBLIC_KEY).toString();
privateKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PRIVATE_KEY).toString();
Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。SUCCESS!");
}
}
注:需要通过RSA工具生成密钥对(公钥&私钥)。
view plain
copyprint?
<filter> <filter-name>SecurityFilter</filter-name> <filter-class>com.wlyd.fmcgwms.util.security.SecurityFilter</filter-class> </filter> <filter-mapping> <filter-name>SecurityFilter</filter-name> <url-pattern>/openapi/*</url-pattern> </filter-mapping>
view plain
copyprint?
package com.wlyd.fmcgwms.controller.security; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.wlyd.fmcgwms.controller.BaseController; import com.wlyd.fmcgwms.util.Tools; /** * 开放API控制层 * * @package com.wlyd.fmcgwms.controller.platform.OpenAPIController * @date 2017年3月14日 下午4:52:12 * @author pengjunlin * @comment * @update */ @Controller @RequestMapping("/openapi") public class OpenAPIController extends BaseController{ /** * 未授权 * * @MethodName: unauthenticated * @Description: * @return * @throws */ @RequestMapping("/unauthenticated") @ResponseBody public String unauthenticated(){ Map<String,Object> map=new HashMap<String, Object>(); map.put("IsSuccess", "false"); map.put("OperationDesc", "Unauthenticated:Please contact to WMS developers!"); return Tools.toJson(map); } /** * 授权成功 * * @MethodName: success * @Description: * @return * @throws */ @RequestMapping("/success") @ResponseBody public String success(){ Map<String,Object> map=new HashMap<String, Object>(); map.put("IsSuccess", "true"); map.put("OperationDesc", "Authenticated!"); return Tools.toJson(map); } }
没有其它的方法。
view plain
copyprint?
package com.wlyd.fmcgwms.util.api;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
/**
* <p>
* RSA公钥/私钥/签名工具包
* </p>
* <p>
* 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)
* </p>
* <p>
* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
* </p>
*
* @author IceWee
* @date 2012-4-26
* @version 1.0
*/
public class RSAUtils {
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* <p>
* 生成密钥对(公钥和私钥)
* </p>
*
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* <p>
* 用私钥对信息生成数字签名
* </p>
*
* @param data
* 已加密数据
* @param privateKey
* 私钥(BASE64编码)
*
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64Utils.encode(signature.sign());
}
/**
* <p>
* 校验数字签名
* </p>
*
* @param data
* 已加密数据
* @param publicKey
* 公钥(BASE64编码)
* @param sign
* 数字签名
*
* @return
* @throws Exception
*
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64Utils.decode(sign));
}
/**
* <P>
* 私钥解密
* </p>
*
* @param encryptedData
* 已加密数据
* @param privateKey
* 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData,
String privateKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher
.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher
.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* <p>
* 公钥解密
* </p>
*
* @param encryptedData
* 已加密数据
* @param publicKey
* 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] encryptedData,
String publicKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher
.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher
.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* <p>
* 公钥加密
* </p>
*
* @param data
* 源数据
* @param publicKey
* 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* <p>
* 私钥加密
* </p>
*
* @param data
* 源数据
* @param privateKey
* 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* <p>
* 获取私钥
* </p>
*
* @param keyMap
* 密钥对
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64Utils.encode(key.getEncoded());
}
/**
* <p>
* 获取公钥
* </p>
*
* @param keyMap
* 密钥对
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64Utils.encode(key.getEncoded());
}
/**
* 将加密后的字节数组转换为对象
*
* @MethodName: bytesToString
* @Description:
* @param encrytpByte
* @return
* @throws
*/
public static String bytesToString(byte[] encrytpByte) {
String result = "";
for (Byte bytes : encrytpByte) {
result += bytes.toString() + " ";
}
return result;
}
/**
* 公钥加密
*
* @MethodName: encrypt
* @Description:
* @param publicKey
* @param obj
* @return
* @throws
*/
public static byte[] encrypt(RSAPublicKey publicKey, byte[] obj) {
if (publicKey != null) {
try {
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 私钥加密
*
* @MethodName: decrypt
* @Description:
* @param privateKey
* @param obj
* @return
* @throws
*/
public static byte[] decrypt(RSAPrivateKey privateKey, byte[] obj) {
if (privateKey != null) {
try {
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
view plain
copyprint?
package com.wlyd.fmcgwms.util;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.wlyd.fmcgwms.persistence.beans.api.AccessToken;
import com.wlyd.fmcgwms.util.api.Base64Utils;
import com.wlyd.fmcgwms.util.api.RSAUtils;
import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;
import com.wlyd.fmcgwms.util.sysinit.InitSysProperties;
/**
* SAAS Token管理工具
*
* @packge com.wlyd.wmscloud.util.SAASTokenManager
* @date 2016年5月6日 上午10:20:01
* @author pengjunlin
* @comment
* @update
*/
public class SAASTokenManager {
/**
* Token存储对象,保持100000个并发容量(K-useraccount@corCode,V-token)
*/
private static final Map<String, Object> map = new ConcurrentHashMap<String, Object>(
100000);
/**
* 获取用户Token
*
* @MethodName: getToken
* @Description:
* @param key
* @return
* @throws
*/
public static AccessToken getToken(String key) {
if (map.containsKey(key)) {
return (AccessToken) map.get(key);
}
return null;
}
/**
* 添加用户token
*
* @MethodName: putToken
* @Description:
* @param key
* useraccount@corCode
* @param accessToken
* @throws
*/
public static void putToken(String key, AccessToken accessToken) {
map.put(key, accessToken);
}
/**
* 移除token
*
* @MethodName: removeToken
* @Description:
* @param key
* useraccount@corCode
* @throws
*/
public static void removeToken(String key) {
if (map.containsKey(key)) {
map.remove(key);
}
}
/**
* 验证Token是否过期
*
* @MethodName: isVlidateToken
* @Description:
* @param key
* useraccount@corCode
* @return
* @throws
*/
public static boolean isVlidateToken(String key) {
if (map.containsKey(key)) {
AccessToken accessToken = (AccessToken) map.get(key);
long currentTimestamp = new Date().getTime();
// 有效时间两小时
if (accessToken.getLongTime() - currentTimestamp > 2 * 3600 * 1000) {
return false;
}
return true;
}
return false;
}
/**
* 更新Token
*
* @MethodName: reputToken
* @Description:
* @param key
* useraccount@corCode
* @param accessToken
* @return
* @throws
*/
public static void reputToken(String key, AccessToken accessToken) {
if (map.containsKey(key)) {
putToken(key, accessToken);
}
}
/**
* 更新Token
*
* @MethodName: reputToken
* @Description:
* @param key
* useraccount@corCode
* @param tokenStr
* @return
* @throws
*/
public static void reputToken(String key, String tokenStr) {
if (map.containsKey(key)) {
AccessToken accessToken = new AccessToken();
accessToken.setToken(tokenStr);
accessToken.setTimestamp(new Timestamp(new Date().getTime()));
putToken(key, accessToken);
}
}
/**
* 是否包含用户token
* @MethodName: iscontainKey
* @Description:
* @param key
* useraccount@corCode
* @return
* @throws
*/
public static boolean iscontainKey(String key){
return map.containsKey(key);
}
/**
* 生成RSA加密 Token
*
* @MethodName: generateToken
* @Description:
* @param platformCode
* @param tenantCode
* @return
* @throws
*/
public static String generateToken(String publicKey,String platformCode,String tenantCode){
String str=platformCode+"$"+tenantCode+"$"+new Date().getTime();
try {
byte [] bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);
// return new String( bytes ,"UTF-8");
return Base64Utils.encode(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 生成RSA加密 Token
*
* @MethodName: generateBytesToken
* @Description:
* @param platformCode
* @param tenantCode
* @return
* @throws
*/
public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode){
byte [] bytes=new byte[0];
String str=platformCode+"$"+tenantCode+"$"+new Date().getTime();
try {
bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);
return bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 生成RSA加密 Token
*
* @MethodName: generateBytesToken
* @Description:
* @param platformCode
* @param tenantCode
* @param regex
* @return
* @throws
*/
public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode,String regex){
byte [] bytes=new byte[0];
String str=platformCode+regex+tenantCode+regex+new Date().getTime();
try {
bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);
return bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 模拟自动生成Token
*
* @MethodName: getToken
* @Description:
* @return
* @throws
*/
public static String getToken(){
// 开启线程同步库存数据到OMS
/*Map<String, Object> keyMap=null;
try {
keyMap = RSAUtils.genKeyPair();
} catch (Exception e) {
e.printStackTrace();
}
String publicKey=null;
try {
publicKey = RSAUtils.getPublicKey(keyMap);
} catch (Exception e) {
e.printStackTrace();
}
String privateKey=null;
try {
privateKey = RSAUtils.getPrivateKey(keyMap);
} catch (Exception e) {
e.printStackTrace();
}*/
String token=null;
try {
String publicKey=EhcacheUtil.get("OMS_RSA_PUBLIC_KEY").toString();
//String privateKey=EhcacheUtil.get("OMS_RSA_PRIVATE_KEY").toString();
String platformCode = (String) EhcacheUtil.get("WAAS_PLATFORMCODE");
String memberCode = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WAAS_MEMBERCODE);
token = SAASTokenManager.generateToken(publicKey, platformCode, memberCode);
if(token!=null){
token.replaceAll("\\n", "");
token.replaceAll("\\r", "");
}
} catch (Exception e) {
Log.getLogger(SAASTokenManager.class).error("Token Error:"+e.getMessage());
e.printStackTrace();
}
return token;
}
/**
* 解密Token
*
* @MethodName: decryptToken
* @Description:
* @param privateKey
* @param token
* @param regex
* @return
* @throws
*/
public static String [] decryptToken(String privateKey,String token,String regex){
String params[]=new String[0];
try {
String[] strArr = token.split(" ");
int len = strArr.length;
// 转回bytes
byte[] clone = new byte[len];
for (int i = 0; i < len; i++) {
clone[i] = Byte.parseByte(strArr[i]);
}
String decryptedToken=new String(RSAUtils.decryptByPrivateKey(clone, privateKey));
params=decryptedToken.split(regex);
} catch (Exception e) {
e.printStackTrace();
}
return params;
}
/**
* @throws Exception
* 测试函数入口
*
* @MethodName: main
* @Description:
* @param args
* @throws
*/
public static void main(String[] args) throws Exception {
System.out.println(Md5.getMD5Str("123456"));
String key = "wmsadmin@10000";
AccessToken accessToken = new AccessToken();
accessToken.setToken("token==xxjisifdihfifdds");
accessToken.setTimestamp(new Timestamp(new Date().getTime()));
putToken(key, accessToken);
AccessToken accessToken2 = getToken(key);
System.out.println("token:" + accessToken2.getToken());
System.out.println("isValidate:" + isVlidateToken(key));
Map<String, Object> keyMap=RSAUtils.genKeyPair();
String publicKey=RSAUtils.getPublicKey(keyMap);
String privateKey=RSAUtils.getPrivateKey(keyMap);
System.out.println("publicKey:\n"+publicKey);
System.out.println("privateKey:\n"+privateKey);
String token=generateToken(publicKey,"1234", "10000");
byte [] bitesToken=RSAUtils.encryptByPublicKey(("1234$10000$"+new Date().getTime()).getBytes(), publicKey);
System.out.println("RSA Token:"+token);
System.out.println("RSA bites Token加密:"+new String(bitesToken,"UTF-8"));
System.out.println("RSA bites Token解密:"+new String(RSAUtils.decryptByPrivateKey(bitesToken, privateKey)));
System.out.println("加密:"+new String(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey),"UTF-8"));
System.out.println("明文:"+new String(RSAUtils.decryptByPrivateKey(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey), privateKey)));
}
}
本文中所述的token我并没有保存下来,而是客户端每次来了都进行验证。
ehcahe配置:ehcache.xml
[html]
view plain
copyprint?
<?xml version="1.0" encoding="UTF-8"?> <!-- 分布式缓存对象同步 采用RMI方式 官方还提供其他同步方式 此处略 --> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <!-- <diskStore path="java.io.tmpdir" /> --> <!--1. 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 --> <!-- <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=manual,rmiUrls=//10.100.0.60:40004/metaCache" /> --> <!--2. 配宿主主机配置监听程序,来发现其他主机发来的同步请求 --> <!-- <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="port=40004,socketTimeoutMillis=120000" />此处默认8000端口 --> <!-- 默认缓存 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="1800" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> <!-- 缓存 --> <cache name="metaCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="0" overflowToDisk="false" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <!-- <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=false, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true "/> <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" properties="bootstrapAsynchronously=false" /> --> </cache> <cache name="REQUESTCACHE" maxElementsInMemory="100000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false" maxElementsOnDisk="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="0" memoryStoreEvictionPolicy="LRU"> </cache> </ehcache>
Ehcache工具类:
[java]
view plain
copyprint?
package com.wlyd.fmcgwms.util.ehcache; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; /** * ehcache 缓存工具类 * * @packge com.wlyd.fmcgwms.util.ehcache.EhcacheUtil * @date 2016年4月28日 下午4:11:27 * @author pengjunlin * @comment cacheName在ehcache.xml中配置 * @update 添加注释,代码重构删除原有类com。wlyd.fmcgwms.util.ehcache.EhcacheUtilOverWrite */ public class EhcacheUtil { public static CacheManager manager = CacheManager.create();// 缓存管理 public static String cacheName = "metaCache";// 缓存名称 /** * 获取缓存对象 * * @MethodName: get * @Description: * @param key * @return * @throws */ public static Object get(Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { Element element = cache.get(key); if (element != null) { return element.getObjectValue(); } } return null; } /** * 获取缓存对象 * * @MethodName: get * @Description: * @param cacheName * @param key * @return * @throws */ public static Object get(String cacheName, Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { Element element = cache.get(key); if (element != null) { return element.getObjectValue(); } } return null; } /** * 添加缓存对象 * * @MethodName: put * @Description: * @param key * @param value * @throws */ public static void put(Object key, Object value) { Cache cache = manager.getCache(cacheName); if (cache != null) { cache.put(new Element(key, value)); } } /** * 添加缓存对象 * * @MethodName: put * @Description: * @param cacheName * @param key * @param value * @throws */ public static void put(String cacheName, Object key, Object value) { Cache cache = manager.getCache(cacheName); if (cache != null) { cache.put(new Element(key, value)); } } /** * 移出缓存对象 * * @MethodName: remove * @Description: * @param key * @return * @throws */ public static boolean remove(Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { return cache.remove(key); } return false; } /** * 移除缓存对象 * * @MethodName: remove * @Description: * @param cacheName * @param key * @return * @throws */ public static boolean remove(String cacheName, Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { return cache.remove(key); } return false; } }
测试方法:
[java]
view plain
copyprint?
package fmcgwms; import org.apache.http.client.methods.HttpGet; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.alibaba.fastjson.JSONObject; import com.wlyd.fmcgwms.util.Md5; import com.wlyd.fmcgwms.util.SAASTokenManager; import com.wlyd.fmcgwms.util.StaticProperty; import com.wlyd.fmcgwms.util.api.APIHttpClient; import com.wlyd.fmcgwms.util.api.RSAUtils; import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil; /** * 开放接口对外模拟测试 * @package fmcgwms.OpenApiTest * @date 2017年3月15日 下午5:51:03 * @author pengjunlin * @comment * @update */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class OpenApiTest {
[java]
view plain
copyprint?
@Test
ublic void testEchcacheToTimeout(){
String requestSequence=Md5.getMD5Str("localhost&interface&opt_type&uniquecode");
System.out.println(">>>>>原始MD5串:"+requestSequence);
EhcacheUtil.put(StaticProperty.REQUESTCACHE, requestSequence, requestSequence);
System.out.println(">>>>>缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence));
try {
Thread.sleep(31000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(">>>>>30s后缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Ehcache的输出:
[plain]
view plain
copyprint?
>>>>>原始MD5串:cae76d65fc5c47875730ed35a262abb4 >>>>>缓存:cae76d65fc5c47875730ed35a262abb4 2017-03-16 15:13:49,647 [net.sf.ehcache.CacheManager@2f1a74d1] INFO [net.sf.ehcache.util.UpdateChecker] - This is the latest GA release. 2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-1] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleFetchInterfaceInfoTaskJob] - >>>WMS-WAAS接口定时任务<<启动失败---fetch----:请设置WAAS_API_ISENABLE=true 2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-2] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleSendInterfaceInfoTaskJob] - >>>WMS-WAAS定时任务<<启动失败----send---:请设置WAAS_API_ISENABLE=true >>>>>30s后缓存:null
转载自:http://blog.csdn.net/boonya/article/details/62423737
设计原理
1.UR拦截请求拦截:通过URL进行拦截过滤;2.接入授权验证:验证请求头Token;
3.请求验重:验证请求序列Sequence;
接口设计文档请参考:WMS系统对外开放接口设计文档-V.1.0.docx
注:文档禁用于商业用途!
安全过滤器
[java]view plain
copyprint?
package com.wlyd.fmcgwms.util.security;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.wlyd.fmcgwms.util.Log;
import com.wlyd.fmcgwms.util.SAASTokenManager;
import com.wlyd.fmcgwms.util.StaticProperty;
import com.wlyd.fmcgwms.util.api.RSAUtils;
import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;
import com.wlyd.fmcgwms.util.sysinit.InitSysProperties;
/**
* 接口安全过滤器
*
* @package com.wlyd.fmcgwms.util.security.SecurityFilter
* @date 2017年3月15日 下午1:57:18
* @author pengjunlin
* @comment
* @update
*/
public class SecurityFilter implements Filter {
private static String API_ISENABLE ;// WMS是否开通对外接口
private static String API_PALTFORM;// WMS开放的平台编码
private static String API_MEMBERCODE;//WMS开放的服务商编码
private static String publicKey;// 公钥
private static String privateKey;// 私钥
@Override
public void destroy() {
// TODO Auto-generated method stub
}
/**
* 验证配置是否规范
*
* @MethodName: isConfiged
* @Description:
* @param platformCode
* @param memberCode
* @return
* @throws
*/
private boolean isConfiged(String platformCode,String memberCode){
if(API_ISENABLE==null||!API_ISENABLE.equals("true")){
return false;
}
if(API_PALTFORM==null||platformCode==null||!platformCode.equals(API_PALTFORM)){
return false;
}
if (API_MEMBERCODE==null||memberCode == null||! memberCode.equals(API_MEMBERCODE)) {
return false;
}
return true;
}
/**
* 验证token是否有效
*
* @MethodName: validateToken
* @Description:
* @param token
* @return
* @throws
*/
private boolean validateToken(String token){
if(token==null||token.equals("")){
return false;
}
String params[]=SAASTokenManager.decryptToken(privateKey, token, "&");
if(params==null||params.length<3){
return false;
}
long now=System.currentTimeMillis();
// Token超时验证20s
long seconds=(now-Long.valueOf(params[2]))/1000;
if(!API_PALTFORM.equals(params[0])||!API_MEMBERCODE.equals(params[1])||seconds>20){
return false;
}
return true;
}
/**
* 验证请求是否重复
*
* @MethodName: validateSequece
* @Description:
* @param sequence
* @return
* @throws
*/
public boolean validateSequece(String sequence){
if(sequence==null||sequence.equals("")){
return false;
}
String requestSequence=(String) EhcacheUtil.get(StaticProperty.REQUESTCACHE, sequence);
// 请求序列相同验证失败
if(requestSequence!=null&&sequence.equals(requestSequence)){
return false;
}
return true;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
PrintWriter out = null;
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String platformCode = req.getHeader("PlatformCode");
String&nb
1d25b
sp;memberCode = req.getHeader("MemberCode");
String token = req.getHeader("Token");
String sequence = req.getHeader("Sequence");
//String path = req.getServletPath();
try {
byte [] bytes=SAASTokenManager.generateBytesToken(publicKey, platformCode, memberCode,"&");
token = RSAUtils.bytesToString(bytes);
} catch (Exception e1) {
e1.printStackTrace();
}
// 验证接口是否配置正确
if(!isConfiged(platformCode, memberCode)){
JSONObject json = new JSONObject();
json.put("IsSuccess", "false");
json.put("OperationDesc", "API parameters are not configed right! ");
json.put("ResultCode", ResultCode.OPEN_API_CONFIG_ERROR);
try {
out = res.getWriter();
out.write(json.toJSONString());
} catch (Exception e) {
e.printStackTrace();
}
return;
}
// 验证Token是否合法
if(!validateToken(token)){
JSONObject json = new JSONObject();
json.put("IsSuccess", "false");
json.put("OperationDesc", "Unauthorized:Token is invalid!");
json.put("ResultCode", ResultCode.OPEN_API_TOKEN_INVALID);
try {
out = res.getWriter();
out.write(json.toJSONString());
} catch (Exception e) {
e.printStackTrace();
}
return;
}
// 验证Sequence是否合法
if(!validateSequece(sequence)){
JSONObject json = new JSONObject();
json.put("IsSuccess", "false");
json.put("OperationDesc", "Refused:request API too frequently!");
json.put("ResultCode", ResultCode.OPEN_API_REQUEST_REQUENTLY);
try {
out = res.getWriter();
out.write(json.toJSONString());
} catch (Exception e) {
e.printStackTrace();
}
return;
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。START!");
API_ISENABLE = InitSysProperties.getLowerCaseFromEhcache(StaticProperty.WMS_OPEN_API_ISENABLE);
API_PALTFORM = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_PLATFORM);
API_MEMBERCODE = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_MEMBERCODE);
publicKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PUBLIC_KEY).toString();
privateKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PRIVATE_KEY).toString();
Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。SUCCESS!");
}
}
package com.wlyd.fmcgwms.util.security; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.alibaba.fastjson.JSONObject; import com.wlyd.fmcgwms.util.Log; import com.wlyd.fmcgwms.util.SAASTokenManager; import com.wlyd.fmcgwms.util.StaticProperty; import com.wlyd.fmcgwms.util.api.RSAUtils; import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil; import com.wlyd.fmcgwms.util.sysinit.InitSysProperties; /** * 接口安全过滤器 * * @package com.wlyd.fmcgwms.util.security.SecurityFilter * @date 2017年3月15日 下午1:57:18 * @author pengjunlin * @comment * @update */ public class SecurityFilter implements Filter { private static String API_ISENABLE ;// WMS是否开通对外接口 private static String API_PALTFORM;// WMS开放的平台编码 private static String API_MEMBERCODE;//WMS开放的服务商编码 private static String publicKey;// 公钥 private static String privateKey;// 私钥 @Override public void destroy() { // TODO Auto-generated method stub } /** * 验证配置是否规范 * * @MethodName: isConfiged * @Description: * @param platformCode * @param memberCode * @return * @throws */ private boolean isConfiged(String platformCode,String memberCode){ if(API_ISENABLE==null||!API_ISENABLE.equals("true")){ return false; } if(API_PALTFORM==null||platformCode==null||!platformCode.equals(API_PALTFORM)){ return false; } if (API_MEMBERCODE==null||memberCode == null||! memberCode.equals(API_MEMBERCODE)) { return false; } return true; } /** * 验证token是否有效 * * @MethodName: validateToken * @Description: * @param token * @return * @throws */ private boolean validateToken(String token){ if(token==null||token.equals("")){ return false; } String params[]=SAASTokenManager.decryptToken(privateKey, token, "&"); if(params==null||params.length<3){ return false; } long now=System.currentTimeMillis(); // Token超时验证20s long seconds=(now-Long.valueOf(params[2]))/1000; if(!API_PALTFORM.equals(params[0])||!API_MEMBERCODE.equals(params[1])||seconds>20){ return false; } return true; } /** * 验证请求是否重复 * * @MethodName: validateSequece * @Description: * @param sequence * @return * @throws */ public boolean validateSequece(String sequence){ if(sequence==null||sequence.equals("")){ return false; } String requestSequence=(String) EhcacheUtil.get(StaticProperty.REQUESTCACHE, sequence); // 请求序列相同验证失败 if(requestSequence!=null&&sequence.equals(requestSequence)){ return false; } return true; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { PrintWriter out = null; HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; String platformCode = req.getHeader("PlatformCode"); String memberCode = req.getHeader("MemberCode"); String token = req.getHeader("Token"); String sequence = req.getHeader("Sequence"); //String path = req.getServletPath(); try { byte [] bytes=SAASTokenManager.generateBytesToken(publicKey, platformCode, memberCode,"&"); token = RSAUtils.bytesToString(bytes); } catch (Exception e1) { e1.printStackTrace(); } // 验证接口是否配置正确 if(!isConfiged(platformCode, memberCode)){ JSONObject json = new JSONObject(); json.put("IsSuccess", "false"); json.put("OperationDesc", "API parameters are not configed right! "); json.put("ResultCode", ResultCode.OPEN_API_CONFIG_ERROR); try { out = res.getWriter(); out.write(json.toJSONString()); } catch (Exception e) { e.printStackTrace(); } return; } // 验证Token是否合法 if(!validateToken(token)){ JSONObject json = new JSONObject(); json.put("IsSuccess", "false"); json.put("OperationDesc", "Unauthorized:Token is invalid!"); json.put("ResultCode", ResultCode.OPEN_API_TOKEN_INVALID); try { out = res.getWriter(); out.write(json.toJSONString()); } catch (Exception e) { e.printStackTrace(); } return; } // 验证Sequence是否合法 if(!validateSequece(sequence)){ JSONObject json = new JSONObject(); json.put("IsSuccess", "false"); json.put("OperationDesc", "Refused:request API too frequently!"); json.put("ResultCode", ResultCode.OPEN_API_REQUEST_REQUENTLY); try { out = res.getWriter(); out.write(json.toJSONString()); } catch (Exception e) { e.printStackTrace(); } return; } chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。START!"); API_ISENABLE = InitSysProperties.getLowerCaseFromEhcache(StaticProperty.WMS_OPEN_API_ISENABLE); API_PALTFORM = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_PLATFORM); API_MEMBERCODE = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_MEMBERCODE); publicKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PUBLIC_KEY).toString(); privateKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PRIVATE_KEY).toString(); Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。SUCCESS!"); } }
注:需要通过RSA工具生成密钥对(公钥&私钥)。
web.xml配置过滤器
[html]view plain
copyprint?
<filter> <filter-name>SecurityFilter</filter-name> <filter-class>com.wlyd.fmcgwms.util.security.SecurityFilter</filter-class> </filter> <filter-mapping> <filter-name>SecurityFilter</filter-name> <url-pattern>/openapi/*</url-pattern> </filter-mapping>
<filter> <filter-name>SecurityFilter</filter-name> <filter-class>com.wlyd.fmcgwms.util.security.SecurityFilter</filter-class> </filter> <filter-mapping> <filter-name>SecurityFilter</filter-name> <url-pattern>/openapi/*</url-pattern> </filter-mapping>
控制层openapi接口
[java]view plain
copyprint?
package com.wlyd.fmcgwms.controller.security; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.wlyd.fmcgwms.controller.BaseController; import com.wlyd.fmcgwms.util.Tools; /** * 开放API控制层 * * @package com.wlyd.fmcgwms.controller.platform.OpenAPIController * @date 2017年3月14日 下午4:52:12 * @author pengjunlin * @comment * @update */ @Controller @RequestMapping("/openapi") public class OpenAPIController extends BaseController{ /** * 未授权 * * @MethodName: unauthenticated * @Description: * @return * @throws */ @RequestMapping("/unauthenticated") @ResponseBody public String unauthenticated(){ Map<String,Object> map=new HashMap<String, Object>(); map.put("IsSuccess", "false"); map.put("OperationDesc", "Unauthenticated:Please contact to WMS developers!"); return Tools.toJson(map); } /** * 授权成功 * * @MethodName: success * @Description: * @return * @throws */ @RequestMapping("/success") @ResponseBody public String success(){ Map<String,Object> map=new HashMap<String, Object>(); map.put("IsSuccess", "true"); map.put("OperationDesc", "Authenticated!"); return Tools.toJson(map); } }
package com.wlyd.fmcgwms.controller.security; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.wlyd.fmcgwms.controller.BaseController; import com.wlyd.fmcgwms.util.Tools; /** * 开放API控制层 * * @package com.wlyd.fmcgwms.controller.platform.OpenAPIController * @date 2017年3月14日 下午4:52:12 * @author pengjunlin * @comment * @update */ @Controller @RequestMapping("/openapi") public class OpenAPIController extends BaseController{ /** * 未授权 * * @MethodName: unauthenticated * @Description: * @return * @throws */ @RequestMapping("/unauthenticated") @ResponseBody public String unauthenticated(){ Map<String,Object> map=new HashMap<String, Object>(); map.put("IsSuccess", "false"); map.put("OperationDesc", "Unauthenticated:Please contact to WMS developers!"); return Tools.toJson(map); } /** * 授权成功 * * @MethodName: success * @Description: * @return * @throws */ @RequestMapping("/success") @ResponseBody public String success(){ Map<String,Object> map=new HashMap<String, Object>(); map.put("IsSuccess", "true"); map.put("OperationDesc", "Authenticated!"); return Tools.toJson(map); } }
没有其它的方法。
RSA加密工具
[java]view plain
copyprint?
package com.wlyd.fmcgwms.util.api;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
/**
* <p>
* RSA公钥/私钥/签名工具包
* </p>
* <p>
* 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)
* </p>
* <p>
* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
* </p>
*
* @author IceWee
* @date 2012-4-26
* @version 1.0
*/
public class RSAUtils {
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* <p>
* 生成密钥对(公钥和私钥)
* </p>
*
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* <p>
* 用私钥对信息生成数字签名
* </p>
*
* @param data
* 已加密数据
* @param privateKey
* 私钥(BASE64编码)
*
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64Utils.encode(signature.sign());
}
/**
* <p>
* 校验数字签名
* </p>
*
* @param data
* 已加密数据
* @param publicKey
* 公钥(BASE64编码)
* @param sign
* 数字签名
*
* @return
* @throws Exception
*
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64Utils.decode(sign));
}
/**
* <P>
* 私钥解密
* </p>
*
* @param encryptedData
* 已加密数据
* @param privateKey
* 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData,
String privateKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher
.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher
.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* <p>
* 公钥解密
* </p>
*
* @param encryptedData
* 已加密数据
* @param publicKey
* 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] encryptedData,
String publicKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher
.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher
.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* <p>
* 公钥加密
* </p>
*
* @param data
* 源数据
* @param publicKey
* 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* <p>
* 私钥加密
* </p>
*
* @param data
* 源数据
* @param privateKey
* 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* <p>
* 获取私钥
* </p>
*
* @param keyMap
* 密钥对
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64Utils.encode(key.getEncoded());
}
/**
* <p>
* 获取公钥
* </p>
*
* @param keyMap
* 密钥对
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64Utils.encode(key.getEncoded());
}
/**
* 将加密后的字节数组转换为对象
*
* @MethodName: bytesToString
* @Description:
* @param encrytpByte
* @return
* @throws
*/
public static String bytesToString(byte[] encrytpByte) {
String result = "";
for (Byte bytes : encrytpByte) {
result += bytes.toString() + " ";
}
return result;
}
/**
* 公钥加密
*
* @MethodName: encrypt
* @Description:
* @param publicKey
* @param obj
* @return
* @throws
*/
public static byte[] encrypt(RSAPublicKey publicKey, byte[] obj) {
if (publicKey != null) {
try {
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 私钥加密
*
* @MethodName: decrypt
* @Description:
* @param privateKey
* @param obj
* @return
* @throws
*/
public static byte[] decrypt(RSAPrivateKey privateKey, byte[] obj) {
if (privateKey != null) {
try {
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
package com.wlyd.fmcgwms.util.api; import java.io.ByteArrayOutputStream; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; /** * <p> * RSA公钥/私钥/签名工具包 * </p> * <p> * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman) * </p> * <p> * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/> * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/> * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 * </p> * * @author IceWee * @date 2012-4-26 * @version 1.0 */ public class RSAUtils { /** * 加密算法RSA */ public static final String KEY_ALGORITHM = "RSA"; /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** * 获取公钥的key */ private static final String PUBLIC_KEY = "RSAPublicKey"; /** * 获取私钥的key */ private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** * <p> * 生成密钥对(公钥和私钥) * </p> * * @return * @throws Exception */ public static Map<String, Object> genKeyPair() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * <p> * 用私钥对信息生成数字签名 * </p> * * @param data * 已加密数据 * @param privateKey * 私钥(BASE64编码) * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return Base64Utils.encode(signature.sign()); } /** * <p> * 校验数字签名 * </p> * * @param data * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @param sign * 数字签名 * * @return * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(Base64Utils.decode(sign)); } /** * <P> * 私钥解密 * </p> * * @param encryptedData * 已加密数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher .doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** * <p> * 公钥解密 * </p> * * @param encryptedData * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher .doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** * <p> * 公钥加密 * </p> * * @param data * 源数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * <p> * 私钥加密 * </p> * * @param data * 源数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * <p> * 获取私钥 * </p> * * @param keyMap * 密钥对 * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return Base64Utils.encode(key.getEnc 2c1de oded()); } /** * <p> * 获取公钥 * </p> * * @param keyMap * 密钥对 * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64Utils.encode(key.getEncoded()); } /** * 将加密后的字节数组转换为对象 * * @MethodName: bytesToString * @Description: * @param encrytpByte * @return * @throws */ public static String bytesToString(byte[] encrytpByte) { String result = ""; for (Byte bytes : encrytpByte) { result += bytes.toString() + " "; } return result; } /** * 公钥加密 * * @MethodName: encrypt * @Description: * @param publicKey * @param obj * @return * @throws */ public static byte[] encrypt(RSAPublicKey publicKey, byte[] obj) { if (publicKey != null) { try { Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(obj); } catch (Exception e) { e.printStackTrace(); } } return null; } /** * 私钥加密 * * @MethodName: decrypt * @Description: * @param privateKey * @param obj * @return * @throws */ public static byte[] decrypt(RSAPrivateKey privateKey, byte[] obj) { if (privateKey != null) { try { Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(obj); } catch (Exception e) { e.printStackTrace(); } } return null; } }
Token管理工具
[java]view plain
copyprint?
package com.wlyd.fmcgwms.util;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.wlyd.fmcgwms.persistence.beans.api.AccessToken;
import com.wlyd.fmcgwms.util.api.Base64Utils;
import com.wlyd.fmcgwms.util.api.RSAUtils;
import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;
import com.wlyd.fmcgwms.util.sysinit.InitSysProperties;
/**
* SAAS Token管理工具
*
* @packge com.wlyd.wmscloud.util.SAASTokenManager
* @date 2016年5月6日 上午10:20:01
* @author pengjunlin
* @comment
* @update
*/
public class SAASTokenManager {
/**
* Token存储对象,保持100000个并发容量(K-useraccount@corCode,V-token)
*/
private static final Map<String, Object> map = new ConcurrentHashMap<String, Object>(
100000);
/**
* 获取用户Token
*
* @MethodName: getToken
* @Description:
* @param key
* @return
* @throws
*/
public static AccessToken getToken(String key) {
if (map.containsKey(key)) {
return (AccessToken) map.get(key);
}
return null;
}
/**
* 添加用户token
*
* @MethodName: putToken
* @Description:
* @param key
* useraccount@corCode
* @param accessToken
* @throws
*/
public static void putToken(String key, AccessToken accessToken) {
map.put(key, accessToken);
}
/**
* 移除token
*
* @MethodName: removeToken
* @Description:
* @param key
* useraccount@corCode
* @throws
*/
public static void removeToken(String key) {
if (map.containsKey(key)) {
map.remove(key);
}
}
/**
* 验证Token是否过期
*
* @MethodName: isVlidateToken
* @Description:
* @param key
* useraccount@corCode
* @return
* @throws
*/
public static boolean isVlidateToken(String key) {
if (map.containsKey(key)) {
AccessToken accessToken = (AccessToken) map.get(key);
long currentTimestamp = new Date().getTime();
// 有效时间两小时
if (accessToken.getLongTime() - currentTimestamp > 2 * 3600 * 1000) {
return false;
}
return true;
}
return false;
}
/**
* 更新Token
*
* @MethodName: reputToken
* @Description:
* @param key
* useraccount@corCode
* @param accessToken
* @return
* @throws
*/
public static void reputToken(String key, AccessToken accessToken) {
if (map.containsKey(key)) {
putToken(key, accessToken);
}
}
/**
* 更新Token
*
* @MethodName: reputToken
* @Description:
* @param key
* useraccount@corCode
* @param tokenStr
* @return
* @throws
*/
public static void reputToken(String key, String tokenStr) {
if (map.containsKey(key)) {
AccessToken accessToken = new AccessToken();
accessToken.setToken(tokenStr);
accessToken.setTimestamp(new Timestamp(new Date().getTime()));
putToken(key, accessToken);
}
}
/**
* 是否包含用户token
* @MethodName: iscontainKey
* @Description:
* @param key
* useraccount@corCode
* @return
* @throws
*/
public static boolean iscontainKey(String key){
return map.containsKey(key);
}
/**
* 生成RSA加密 Token
*
* @MethodName: generateToken
* @Description:
* @param platformCode
* @param tenantCode
* @return
* @throws
*/
public static String generateToken(String publicKey,String platformCode,String tenantCode){
String str=platformCode+"$"+tenantCode+"$"+new Date().getTime();
try {
byte [] bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);
// return new String( bytes ,"UTF-8");
return Base64Utils.encode(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 生成RSA加密 Token
*
* @MethodName: generateBytesToken
* @Description:
* @param platformCode
* @param tenantCode
* @return
* @throws
*/
public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode){
byte [] bytes=new byte[0];
String str=platformCode+"$"+tenantCode+"$"+new Date().getTime();
try {
bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);
return bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 生成RSA加密 Token
*
* @MethodName: generateBytesToken
* @Description:
* @param platformCode
* @param tenantCode
* @param regex
* @return
* @throws
*/
public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode,String regex){
byte [] bytes=new byte[0];
String str=platformCode+regex+tenantCode+regex+new Date().getTime();
try {
bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);
return bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 模拟自动生成Token
*
* @MethodName: getToken
* @Description:
* @return
* @throws
*/
public static String getToken(){
// 开启线程同步库存数据到OMS
/*Map<String, Object> keyMap=null;
try {
keyMap = RSAUtils.genKeyPair();
} catch (Exception e) {
e.printStackTrace();
}
String publicKey=null;
try {
publicKey = RSAUtils.getPublicKey(keyMap);
} catch (Exception e) {
e.printStackTrace();
}
String privateKey=null;
try {
privateKey = RSAUtils.getPrivateKey(keyMap);
} catch (Exception e) {
e.printStackTrace();
}*/
String token=null;
try {
String publicKey=EhcacheUtil.get("OMS_RSA_PUBLIC_KEY").toString();
//String privateKey=EhcacheUtil.get("OMS_RSA_PRIVATE_KEY").toString();
String platformCode = (String) EhcacheUtil.get("WAAS_PLATFORMCODE");
String memberCode = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WAAS_MEMBERCODE);
token = SAASTokenManager.generateToken(publicKey, platformCode, memberCode);
if(token!=null){
token.replaceAll("\\n", "");
token.replaceAll("\\r", "");
}
} catch (Exception e) {
Log.getLogger(SAASTokenManager.class).error("Token Error:"+e.getMessage());
e.printStackTrace();
}
return token;
}
/**
* 解密Token
*
* @MethodName: decryptToken
* @Description:
* @param privateKey
* @param token
* @param regex
* @return
* @throws
*/
public static String [] decryptToken(String privateKey,String token,String regex){
String params[]=new String[0];
try {
String[] strArr = token.split(" ");
int len = strArr.length;
// 转回bytes
byte[] clone = new byte[len];
for (int i = 0; i < len; i++) {
clone[i] = Byte.parseByte(strArr[i]);
}
String decryptedToken=new String(RSAUtils.decryptByPrivateKey(clone, privateKey));
params=decryptedToken.split(regex);
} catch (Exception e) {
e.printStackTrace();
}
return params;
}
/**
* @throws Exception
* 测试函数入口
*
* @MethodName: main
* @Description:
* @param args
* @throws
*/
public static void main(String[] args) throws Exception {
System.out.println(Md5.getMD5Str("123456"));
String key = "wmsadmin@10000";
AccessToken accessToken = new AccessToken();
accessToken.setToken("token==xxjisifdihfifdds");
accessToken.setTimestamp(new Timestamp(new Date().getTime()));
putToken(key, accessToken);
AccessToken accessToken2 = getToken(key);
System.out.println("token:" + accessToken2.getToken());
System.out.println("isValidate:" + isVlidateToken(key));
Map<String, Object> keyMap=RSAUtils.genKeyPair();
String publicKey=RSAUtils.getPublicKey(keyMap);
String privateKey=RSAUtils.getPrivateKey(keyMap);
System.out.println("publicKey:\n"+publicKey);
System.out.println("privateKey:\n"+privateKey);
String token=generateToken(publicKey,"1234", "10000");
byte [] bitesToken=RSAUtils.encryptByPublicKey(("1234$10000$"+new Date().getTime()).getBytes(), publicKey);
System.out.println("RSA Token:"+token);
System.out.println("RSA bites Token加密:"+new String(bitesToken,"UTF-8"));
System.out.println("RSA bites Token解密:"+new String(RSAUtils.decryptByPrivateKey(bitesToken, privateKey)));
System.out.println("加密:"+new String(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey),"UTF-8"));
System.out.println("明文:"+new String(RSAUtils.decryptByPrivateKey(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey), privateKey)));
}
}
package com.wlyd.fmcgwms.util; import java.sql.Timestamp; import java.util.Date; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import com.wlyd.fmcgwms.persistence.beans.api.AccessToken; import com.wlyd.fmcgwms.util.api.Base64Utils; import com.wlyd.fmcgwms.util.api.RSAUtils; import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil; import com.wlyd.fmcgwms.util.sysinit.InitSysProperties; /** * SAAS Token管理工具 * * @packge com.wlyd.wmscloud.util.SAASTokenManager * @date 2016年5月6日 上午10:20:01 * @author pengjunlin * @comment * @update */ public class SAASTokenManager { /** * Token存储对象,保持100000个并发容量(K-useraccount@corCode,V-token) */ private static final Map<String, Object> map = new ConcurrentHashMap<String, Object>( 100000); /** * 获取用户Token * * @MethodName: getToken * @Description: * @param key * @return * @throws */ public static AccessToken getToken(String key) { if (map.containsKey(key)) { return (AccessToken) map.get(key); } return null; } /** * 添加用户token * * @MethodName: putToken * @Description: * @param key * useraccount@corCode * @param accessToken * @throws */ public static void putToken(String key, AccessToken accessToken) { map.put(key, accessToken); } /** * 移除token * * @MethodName: removeToken * @Description: * @param key * useraccount@corCode * @throws */ public static void removeToken(String key) { if (map.containsKey(key)) { map.remove(key); } } /** * 验证Token是否过期 * * @MethodName: isVlidateToken * @Description: * @param key * useraccount@corCode * @return * @throws */ public static boolean isVlidateToken(String key) { if (map.containsKey(key)) { AccessToken accessToken = (AccessToken) map.get(key); long currentTimestamp = new Date().getTime(); // 有效时间两小时 if (accessToken.getLongTime() - currentTimestamp > 2 * 3600 * 1000) { return false; } return true; } return false; } /** * 更新Token * * @MethodName: reputToken * @Description: * @param key * useraccount@corCode * @param accessToken * @return * @throws */ public static void reputToken(String key, AccessToken accessToken) { if (map.containsKey(key)) { putToken(key, accessToken); } } /** * 更新Token * * @MethodName: reputToken * @Description: * @param key * useraccount@corCode * @param tokenStr * @return * @throws */ public static void reputToken(String key, String tokenStr) { if (map.containsKey(key)) { AccessToken accessToken = new AccessToken(); accessToken.setToken(tokenStr); accessToken.setTimestamp(new Timestamp(new Date().getTime())); putToken(key, accessToken); } } /** * 是否包含用户token * @MethodName: iscontainKey * @Description: * @param key * useraccount@corCode * @return * @throws */ public static boolean iscontainKey(String key){ return map.containsKey(key); } /** * 生成RSA加密 Token * * @MethodName: generateToken * @Description: * @param platformCode * @param tenantCode * @return * @throws */ public static String generateToken(String publicKey,String platformCode,String tenantCode){ String str=platformCode+"$"+tenantCode+"$"+new Date().getTime(); try { byte [] bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey); // return new String( bytes ,"UTF-8"); return Base64Utils.encode(bytes); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 生成RSA加密 Token * * @MethodName: generateBytesToken * @Description: * @param platformCode * @param tenantCode * @return * @throws */ public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode){ byte [] bytes=new byte[0]; String str=platformCode+"$"+tenantCode+"$"+new Date().getTime(); try { bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey); return bytes; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 生成RSA加密 Token * * @MethodName: generateBytesToken * @Description: * @param platformCode * @param tenantCode * @param regex * @return * @throws */ public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode,String regex){ byte [] bytes=new byte[0]; String str=platformCode+regex+tenantCode+regex+new Date().getTime(); try { bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey); return bytes; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 模拟自动生成Token * * @MethodName: getToken * @Description: * @return * @throws */ public static String getToken(){ // 开启线程同步库存数据到OMS /*Map<String, Object> keyMap=null; try { keyMap = RSAUtils.genKeyPair(); } catch (Exception e) { e.printStackTrace(); } String publicKey=null; try { publicKey = RSAUtils.getPublicKey(keyMap); } catch (Exception e) { e.printStackTrace(); } String privateKey=null; try { privateKey = RSAUtils.getPrivateKey(keyMap); } catch (Exception e) { e.printStackTrace(); }*/ String token=null; try { String publicKey=EhcacheUtil.get("OMS_RSA_PUBLIC_KEY").toString(); //String privateKey=EhcacheUtil.get("OMS_RSA_PRIVATE_KEY").toString(); String platformCode = (String) EhcacheUtil.get("WAAS_PLATFORMCODE"); String memberCode = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WAAS_MEMBERCODE); token = SAASTokenManager.generateToken(publicKey, platformCode, memberCode); if(token!=null){ token.replaceAll("\\n", ""); token.replaceAll("\\r", ""); } } catch (Exception e) { Log.getLogger(SAASTokenManager.class).error("Token Error:"+e.getMessage()); e.printStackTrace(); } return token; } /** * 解密Token * * @MethodName: decryptToken * @Description: * @param privateKey * @param token * @param regex * @return * @throws */ public static String [] decryptToken(String privateKey,String token,String regex){ String params[]=new String[0]; try { String[] strArr = token.split(" "); int len = strArr.length; // 转回bytes byte[] clone = new byte[len]; for (int i = 0; i < len; i++) { clone[i] = Byte.parseByte(strArr[i]); } String decryptedToken=new String(RSAUtils.decryptByPrivateKey(clone, privateKey)); params=decryptedToken.split(regex); } catch (Exception e) { e.printStackTrace(); } return params; } /** * @throws Exception * 测试函数入口 * * @MethodName: main * @Description: * @param args * @throws */ public static void main(String[] args) throws Exception { System.out.println(Md5.getMD5Str("123456")); String key = "wmsadmin@10000"; AccessToken accessToken = new AccessToken(); accessToken.setToken("token==xxjisifdihfifdds"); accessToken.setTimestamp(new Timestamp(new Date().getTime())); putToken(key, accessToken); AccessToken accessToken2 = getToken(key); System.out.println("token:" + accessToken2.getToken()); System.out.println("isValidate:" + isVlidateToken(key)); Map<String, Object> keyMap=RSAUtils.genKeyPair(); String publicKey=RSAUtils.getPublicKey(keyMap); String privateKey=RSAUtils.getPrivateKey(keyMap); System.out.println("publicKey:\n"+publicKey); System.out.println("privateKey:\n"+privateKey); String token=generateToken(publicKey,"1234", "10000"); byte [] bitesToken=RSAUtils.encryptByPublicKey(("1234$10000$"+new Date().getTime()).getBytes(), publicKey); System.out.println("RSA Token:"+token); System.out.println("RSA bites Token加密:"+new String(bitesToken,"UTF-8")); System.out.println("RSA bites Token解密:"+new String(RSAUtils.decryptByPrivateKey(bitesToken, privateKey))); System.out.println("加密:"+new String(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey),"UTF-8")); System.out.println("明文:"+new String(RSAUtils.decryptByPrivateKey(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey), privateKey))); } }
本文中所述的token我并没有保存下来,而是客户端每次来了都进行验证。
Ehcache缓存请求30s验重
缓存方案你也可以用Redis来做,这里因为项目使用的是Ehcache故将就之。ehcahe配置:ehcache.xml
[html]
view plain
copyprint?
<?xml version="1.0" encoding="UTF-8"?> <!-- 分布式缓存对象同步 采用RMI方式 官方还提供其他同步方式 此处略 --> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <!-- <diskStore path="java.io.tmpdir" /> --> <!--1. 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 --> <!-- <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=manual,rmiUrls=//10.100.0.60:40004/metaCache" /> --> <!--2. 配宿主主机配置监听程序,来发现其他主机发来的同步请求 --> <!-- <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="port=40004,socketTimeoutMillis=120000" />此处默认8000端口 --> <!-- 默认缓存 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="1800" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> <!-- 缓存 --> <cache name="metaCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="0" overflowToDisk="false" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <!-- <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=false, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true "/> <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" properties="bootstrapAsynchronously=false" /> --> </cache> <cache name="REQUESTCACHE" maxElementsInMemory="100000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false" maxElementsOnDisk="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="0" memoryStoreEvictionPolicy="LRU"> </cache> </ehcache>
<?xml version="1.0" encoding="UTF-8"?> <!-- 分布式缓存对象同步 采用RMI方式 官方还提供其他同步方式 此处略 --> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <!-- <diskStore path="java.io.tmpdir" /> --> <!--1. 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 --> <!-- <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=manual,rmiUrls=//10.100.0.60:40004/metaCache" /> --> <!--2. 配宿主主机配置监听程序,来发现其他主机发来的同步请求 --> <!-- <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="port=40004,socketTimeoutMillis=120000" />此处默认8000端口 --> <!-- 默认缓存 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="1800" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> <!-- 缓存 --> <cache name="metaCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="0" overflowToDisk="false" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <!-- <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" properties="replicateAsynchronously=true, replicatePuts=false, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true "/> <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" properties="bootstrapAsynchronously=false" /> --> </cache> <cache name="REQUESTCACHE" maxElementsInMemory="100000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false" maxElementsOnDisk="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="0" memoryStoreEvictionPolicy="LRU"> </cache> </ehcache>
Ehcache工具类:
[java]
view plain
copyprint?
package com.wlyd.fmcgwms.util.ehcache; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; /** * ehcache 缓存工具类 * * @packge com.wlyd.fmcgwms.util.ehcache.EhcacheUtil * @date 2016年4月28日 下午4:11:27 * @author pengjunlin * @comment cacheName在ehcache.xml中配置 * @update 添加注释,代码重构删除原有类com。wlyd.fmcgwms.util.ehcache.EhcacheUtilOverWrite */ public class EhcacheUtil { public static CacheManager manager = CacheManager.create();// 缓存管理 public static String cacheName = "metaCache";// 缓存名称 /** * 获取缓存对象 * * @MethodName: get * @Description: * @param key * @return * @throws */ public static Object get(Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { Element element = cache.get(key); if (element != null) { return element.getObjectValue(); } } return null; } /** * 获取缓存对象 * * @MethodName: get * @Description: * @param cacheName * @param key * @return * @throws */ public static Object get(String cacheName, Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { Element element = cache.get(key); if (element != null) { return element.getObjectValue(); } } return null; } /** * 添加缓存对象 * * @MethodName: put * @Description: * @param key * @param value * @throws */ public static void put(Object key, Object value) { Cache cache = manager.getCache(cacheName); if (cache != null) { cache.put(new Element(key, value)); } } /** * 添加缓存对象 * * @MethodName: put * @Description: * @param cacheName * @param key * @param value * @throws */ public static void put(String cacheName, Object key, Object value) { Cache cache = manager.getCache(cacheName); if (cache != null) { cache.put(new Element(key, value)); } } /** * 移出缓存对象 * * @MethodName: remove * @Description: * @param key * @return * @throws */ public static boolean remove(Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { return cache.remove(key); } return false; } /** * 移除缓存对象 * * @MethodName: remove * @Description: * @param cacheName * @param key * @return * @throws */ public static boolean remove(String cacheName, Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { return cache.remove(key); } return false; } }
package com.wlyd.fmcgwms.util.ehcache; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; /** * ehcache 缓存工具类 * * @packge com.wlyd.fmcgwms.util.ehcache.EhcacheUtil * @date 2016年4月28日 下午4:11:27 * @author pengjunlin * @comment cacheName在ehcache.xml中配置 * @update 添加注释,代码重构删除原有类com。wlyd.fmcgwms.util.ehcache.EhcacheUtilOverWrite */ public class EhcacheUtil { public static CacheManager manager = CacheManager.create();// 缓存管理 public static String cacheName = "metaCache";// 缓存名称 /** * 获取缓存对象 * * @MethodName: get * @Description: * @param key * @return * @throws */ public static Object get(Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { Element element = cache.get(key); if (element != null) { return element.getObjectValue(); } } return null; } /** * 获取缓存对象 * * @MethodName: get * @Description: * @param cacheName * @param key * @return * @throws */ public static Object get(String cacheName, Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { Element element = cache.get(key); if (element != null) { return element.getObjectValue(); } } return null; } /** * 添加缓存对象 * * @MethodName: put * @Description: * @param key * @param value * @throws */ public static void put(Object key, Object value) { Cache cache = manager.getCache(cacheName); if (cache != null) { cache.put(new Element(key, value)); } } /** * 添加缓存对象 * * @MethodName: put * @Description: * @param cacheName * @param key * @param value * @throws */ public static void put(String cacheName, Object key, Object value) { Cache cache = manager.getCache(cacheName); if (cache != null) { cache.put(new Element(key, value)); } } /** * 移出缓存对象 * * @MethodName: remove * @Description: * @param key * @return * @throws */ public static boolean remove(Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { return cache.remove(key); } return false; } /** * 移除缓存对象 * * @MethodName: remove * @Description: * @param cacheName * @param key * @return * @throws */ public static boolean remove(String cacheName, Object key) { Cache cache = manager.getCache(cacheName); if (cache != null) { return cache.remove(key); } return false; } }
测试方法:
[java]
view plain
copyprint?
package fmcgwms; import org.apache.http.client.methods.HttpGet; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.alibaba.fastjson.JSONObject; import com.wlyd.fmcgwms.util.Md5; import com.wlyd.fmcgwms.util.SAASTokenManager; import com.wlyd.fmcgwms.util.StaticProperty; import com.wlyd.fmcgwms.util.api.APIHttpClient; import com.wlyd.fmcgwms.util.api.RSAUtils; import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil; /** * 开放接口对外模拟测试 * @package fmcgwms.OpenApiTest * @date 2017年3月15日 下午5:51:03 * @author pengjunlin * @comment * @update */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class OpenApiTest {
package fmcgwms; import org.apache.http.client.methods.HttpGet; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.alibaba.fastjson.JSONObject; import com.wlyd.fmcgwms.util.Md5; import com.wlyd.fmcgwms.util.SAASTokenManager; import com.wlyd.fmcgwms.util.StaticProperty; import com.wlyd.fmcgwms.util.api.APIHttpClient; import com.wlyd.fmcgwms.util.api.RSAUtils; import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil; /** * 开放接口对外模拟测试 * @package fmcgwms.OpenApiTest * @date 2017年3月15日 下午5:51:03 * @author pengjunlin * @comment * @update */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class OpenApiTest {
[java]
view plain
copyprint?
@Test
ublic void testEchcacheToTimeout(){
String requestSequence=Md5.getMD5Str("localhost&interface&opt_type&uniquecode");
System.out.println(">>>>>原始MD5串:"+requestSequence);
EhcacheUtil.put(StaticProperty.REQUESTCACHE, requestSequence, requestSequence);
System.out.println(">>>>>缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence));
try {
Thread.sleep(31000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(">>>>>30s后缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
@Test public void testEchcacheToTimeout(){ String requestSequence=Md5.getMD5Str("localhost&interface&opt_type&uniquecode"); System.out.println(">>>>>原始MD5串:"+requestSequence); EhcacheUtil.put(StaticProperty.REQUESTCACHE, requestSequence, requestSequence); System.out.println(">>>>>缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence)); try { Thread.sleep(31000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(">>>>>30s后缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence)); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } }
Ehcache的输出:
[plain]
view plain
copyprint?
>>>>>原始MD5串:cae76d65fc5c47875730ed35a262abb4 >>>>>缓存:cae76d65fc5c47875730ed35a262abb4 2017-03-16 15:13:49,647 [net.sf.ehcache.CacheManager@2f1a74d1] INFO [net.sf.ehcache.util.UpdateChecker] - This is the latest GA release. 2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-1] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleFetchInterfaceInfoTaskJob] - >>>WMS-WAAS接口定时任务<<启动失败---fetch----:请设置WAAS_API_ISENABLE=true 2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-2] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleSendInterfaceInfoTaskJob] - >>>WMS-WAAS定时任务<<启动失败----send---:请设置WAAS_API_ISENABLE=true >>>>>30s后缓存:null
>>>>>原始MD5串:cae76d65fc5c47875730ed35a262abb4 >>>>>缓存:cae76d65fc5c47875730ed35a262abb4 2017-03-16 15:13:49,647 [net.sf.ehcache.CacheManager@2f1a74d1] INFO [net.sf.ehcache.util.UpdateChecker] - This is the latest GA release. 2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-1] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleFetchInterfaceInfoTaskJob] - >>>WMS-WAAS接口定时任务<<启动失败---fetch----:请设置WAAS_API_ISENABLE=true 2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-2] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleSendInterfaceInfoTaskJob] - >>>WMS-WAAS定时任务<<启动失败----send---:请设置WAAS_API_ISENABLE=true >>>>>30s后缓存:null
转载自:http://blog.csdn.net/boonya/article/details/62423737
相关文章推荐
- Spring设计安全的Restful接口-无用户状态的安全
- 开放接口/RESTful/Api服务的设计和安全方案
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(二)RESTful API实战笔记(接口设计及Java后端实现)
- RESTful登录设计(基于Spring及Redis的Token鉴权)
- PHP与Spring之间的强势接口设计:学习案例
- PHP与Spring的强势接口设计_微课介绍
- 如何写出安全的API接口?接口参数加密签名设计思路
- 【每日一博】Spring 文件上传接口设计与实现
- 理解并设计rest/restful风格接口
- Spring Boot系列八 spring boot集成jsp、restful接口、springmvc基本功能
- Java版本APP接口安全设计
- 使用CXF+spring+restful创建一个web的接口项目
- 设计安全的接口api
- Restful风格的接口设计
- 如何写出安全的API接口?接口参数加密签名设计思路
- Spring源码解析之IoC容器主要接口设计
- 使用CXF+spring+restful创建一个web的接口项目
- RESTful设计原则和样例(开发前后台接口)
- Swagger+Spring mvc生成Restful接口文档