json转换

This commit is contained in:
jjLv 2025-04-14 23:57:22 +08:00
parent cd5e7096bb
commit 5d4ea5327d
9 changed files with 1142 additions and 0 deletions

View File

@ -0,0 +1,242 @@
package com.bonus.canteen.core.config;
import cn.hutool.core.util.ArrayUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@JsonIgnoreProperties(
ignoreUnknown = true
)
public class AccessToken {
private static final Logger log = LoggerFactory.getLogger(AccessToken.class);
@JsonIgnore
protected static ObjectMapper objectMapper;
@JsonIgnore
protected static SecureProperties secureProperties;
@JsonIgnore
protected static StringRedisTemplate redisTemplate;
@JsonIgnore
protected static AuthenticationPredicate authenticationPredicate;
private String id;
private Long subjectId;
private String subjectName;
private Map<String, String> subjectData = Maps.newHashMap();
private String scope;
private boolean identified;
private long createTime;
private long lastTime;
public static Optional<AccessToken> recovery(String clientToken) {
StringRedisTemplate var10000 = redisTemplate;
String var10001 = secureProperties.getServer().getStoreKey();
clientToken = (String)var10000.boundValueOps(var10001 + ":" + clientToken).get();
if (StringUtils.isBlank(clientToken)) {
return Optional.empty();
} else {
try {
AccessToken existToken = (AccessToken)objectMapper.readValue(clientToken, AccessToken.class);
return authenticationPredicate.authenticated(existToken) ? Optional.of(existToken) : Optional.empty();
} catch (Exception var2) {
log.error("Deserialize exist token error", var2);
return Optional.empty();
}
}
}
public static AccessToken create(long subjectId) {
AccessToken accessToken = create();
accessToken.setSubjectId(subjectId);
return accessToken;
}
public static AccessToken create(long subjectId, String subjectName) {
AccessToken accessToken = create(subjectId);
accessToken.setSubjectName(subjectName);
return accessToken;
}
public static AccessToken create() {
AccessToken accessToken = new AccessToken();
accessToken.setId(UUID.randomUUID().toString());
accessToken.setCreateTime(Instant.now().getEpochSecond());
accessToken.setLastTime(Instant.now().getEpochSecond());
return accessToken;
}
public AccessToken touch() {
this.identified = this.isAuthenticated();
this.lastTime = Instant.now().getEpochSecond();
return this.store();
}
@JsonIgnore
public boolean isAuthenticated() {
return this.identified && !this.isExpired();
}
@JsonIgnore
private boolean isExpired() {
return this.lastTime + secureProperties.getExpireAfter() < Instant.now().getEpochSecond();
}
public AccessToken withData(Map<String, String> data) {
this.subjectData = data;
return this;
}
public AccessToken setData(String name, String value) {
this.subjectData.put(name, value);
return this;
}
public AccessToken removeData(String... keys) {
if (ArrayUtil.isEmpty(keys)) {
return this;
} else {
String[] var2 = keys;
int var3 = keys.length;
for(int var4 = 0; var4 < var3; ++var4) {
String key = var2[var4];
this.subjectData.remove(key);
}
return this;
}
}
public AccessToken revokeAuthenticate() {
this.identified = false;
return this.store();
}
public AccessToken authenticate() {
if (this.subjectId == null) {
throw new RuntimeException("required subjectId is not provide");
} else {
this.identified = true;
return this;
}
}
public AccessToken store() {
try {
StringRedisTemplate var10000 = redisTemplate;
DefaultRedisScript var10001 = new DefaultRedisScript("redis.call('SET',KEYS[1],ARGV[1],'EX',ARGV[3]);redis.call('SET',KEYS[2],ARGV[2],'EX',ARGV[3]);");
String[] var10002 = new String[2];
String var10005 = secureProperties.getServer().getStoreKey();
var10002[0] = var10005 + ":" + this.getId();
var10005 = secureProperties.getServer().getSubjectRefTokenKey();
var10002[1] = var10005 + ":" + this.getSubjectId() + ":" + this.getId() + ":" + this.getCreateTime();
var10000.execute(var10001, Lists.newArrayList(var10002), new Object[]{objectMapper.writeValueAsString(this), this.getId(), String.valueOf(secureProperties.getServer().getTtl())});
} catch (Exception var2) {
log.error("Token store error", var2);
}
return this;
}
public AccessToken bind() {
WebContext.get().setAccessToken(this);
return this;
}
public void write() {
WebContext.get().getResponse().ifPresent((response) -> {
response.setHeader(secureProperties.getTokenSymbol(), this.getId());
});
}
public void clear() {
try {
StringRedisTemplate var10000 = redisTemplate;
DefaultRedisScript var10001 = new DefaultRedisScript("redis.call('DEL',KEYS[1],KEYS[2]);");
String[] var10002 = new String[2];
String var10005 = secureProperties.getServer().getStoreKey();
var10002[0] = var10005 + ":" + this.getId();
var10005 = secureProperties.getServer().getSubjectRefTokenKey();
var10002[1] = var10005 + ":" + this.getSubjectId() + ":" + this.getId() + ":" + this.getCreateTime();
var10000.execute(var10001, Lists.newArrayList(var10002), new Object[0]);
} catch (Exception var2) {
log.error("Token clear error", var2);
}
}
public String getId() {
return this.id;
}
public Long getSubjectId() {
return this.subjectId;
}
public String getSubjectName() {
return this.subjectName;
}
public Map<String, String> getSubjectData() {
return this.subjectData;
}
public String getScope() {
return this.scope;
}
public boolean isIdentified() {
return this.identified;
}
public long getCreateTime() {
return this.createTime;
}
public long getLastTime() {
return this.lastTime;
}
public void setId(final String id) {
this.id = id;
}
public void setSubjectId(final Long subjectId) {
this.subjectId = subjectId;
}
public void setSubjectName(final String subjectName) {
this.subjectName = subjectName;
}
public void setSubjectData(final Map<String, String> subjectData) {
this.subjectData = subjectData;
}
public void setScope(final String scope) {
this.scope = scope;
}
public void setIdentified(final boolean identified) {
this.identified = identified;
}
public void setCreateTime(final long createTime) {
this.createTime = createTime;
}
public void setLastTime(final long lastTime) {
this.lastTime = lastTime;
}
}

View File

@ -0,0 +1,5 @@
package com.bonus.canteen.core.config;
public interface AuthenticationPredicate {
boolean authenticated(AccessToken accessToken);
}

View File

@ -0,0 +1,154 @@
package com.bonus.canteen.core.config;//package com.bonus.canteen.core.config;
//
//import cn.hutool.core.map.MapUtil;
//import com.bonus.canteen.core.customer.service.AuthorizingService;
//import com.bonus.canteen.core.secure.PmsCache;
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.google.common.collect.Maps;
//import com.google.common.collect.Sets;
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.collections4.ListUtils;
//import org.apache.commons.lang3.BooleanUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.data.redis.core.BoundHashOperations;
//import org.springframework.data.redis.core.StringRedisTemplate;
//import java.time.Instant;
//import java.util.*;
//import java.util.function.Function;
//import java.util.stream.Collectors;
//import java.util.stream.Stream;
//
//public class SecureManager {
// private static final Logger log = LoggerFactory.getLogger(SecureManager.class);
// private static SecureProperties secureProperties;
// private static StringRedisTemplate redisTemplate;
// private static AuthorizingService authorizingService;
// private static ObjectMapper objectMapper;
//
// private SecureManager() {
// }
//
// public static void setSecureProperties(SecureProperties secureProperties) {
// if (SecureManager.secureProperties == null) {
// SecureManager.secureProperties = secureProperties;
// }
// }
//
// public static void setRedisTemplate(StringRedisTemplate redisTemplate) {
// if (SecureManager.redisTemplate == null) {
// SecureManager.redisTemplate = redisTemplate;
// }
// }
//
// public static void setAuthorizingService(AuthorizingService authorizingService) {
// if (SecureManager.authorizingService == null) {
// SecureManager.authorizingService = authorizingService;
// }
// }
//
// public static void setObjectMapper(ObjectMapper objectMapper) {
// if (SecureManager.objectMapper == null) {
// SecureManager.objectMapper = objectMapper;
// }
// }
//
// private static String getPmsKey(long subjectId) {
// return "permissions:subject_id:" + subjectId;
// }
//
// private static String getRoleKey(long subjectId) {
// return "roles:subject_id:" + subjectId;
// }
//
// public static void clearAllRoleAndPermission() {
// redisTemplate.delete(secureProperties.getPermissionKey());
// }
//
// public static void clearRoleAndPermission(long subjectId) {
// redisTemplate.boundHashOps(secureProperties.getPermissionKey()).delete(new Object[]{getRoleKey(subjectId), getPmsKey(subjectId)});
// }
//
// public static void clearRole(long subjectId) {
// redisTemplate.boundHashOps(secureProperties.getPermissionKey()).delete(new Object[]{getRoleKey(subjectId)});
// }
//
// public static void clearPermission(long subjectId) {
// redisTemplate.boundHashOps(secureProperties.getPermissionKey()).delete(new Object[]{getPmsKey(subjectId)});
// }
//
// public static boolean isLogin() {
// return (Boolean)WebContext.get().getAccessToken().map(AccessToken::isAuthenticated).orElse(false);
// }
//
// public static Optional<Long> getSubjectId() {
// return WebContext.get().getAccessToken().map(AccessToken::getSubjectId);
// }
//
// public static Optional<String> getSubjectName() {
// return WebContext.get().getAccessToken().map(AccessToken::getSubjectName);
// }
//
// public static Map<String, String> getSubjectData() {
// return (Map)WebContext.get().getAccessToken().map(AccessToken::getSubjectData).orElse(Maps.newHashMap());
// }
//
// public static Map<String, String> attachData(Map<String, String> data) {
// try {
// if (MapUtil.isEmpty(data)) {
// return Maps.newHashMapWithExpectedSize(0);
// } else {
// AccessToken accessToken = (AccessToken)WebContext.get().getAccessToken().orElse(AccessToken.create());
// Objects.requireNonNull(accessToken);
// data.forEach(accessToken::setData);
// accessToken.bind().store();
// return accessToken.getSubjectData();
// }
// } catch (Throwable var2) {
// throw var2;
// }
// }
//
// public static Map<String, String> attachData(String key, String value) {
// try {
// return attachData(Collections.singletonMap(key, value));
// } catch (Throwable var3) {
// throw var3;
// }
// }
//
// public static void logout() {
// WebContext.get().getAccessToken().ifPresent(AccessToken::clear);
// }
//
// public static void revokeAuthenticate() {
// WebContext.get().getAccessToken().ifPresent((accessToken) -> {
// accessToken.revokeAuthenticate().store();
// });
// }
//
// public static void revokeAuthenticate(long subjectId, int reservedRecentNum) {
// StringRedisTemplate var10000 = redisTemplate;
// String var10001 = secureProperties.getServer().getSubjectRefTokenKey();
// Set<String> keys = var10000.keys(var10001 + ":" + subjectId + ":*");
// if (CollectionUtils.size(keys) > reservedRecentNum) {
// assert keys != null;
//
// Map<Long, List<String>> createTimeAsc_keys = (Map)keys.stream().collect(Collectors.groupingBy((key) -> {
// return Long.parseLong(key.split(":")[4]);
// }, TreeMap::new, Collectors.toList()));
// List<String> keysAsc = createTimeAsc_keys.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
// List<String> beDeleteRefKeys = keysAsc.subList(0, keysAsc.size() - reservedRecentNum);
// List<String> beDeleteTokenKeys = beDeleteRefKeys.stream().map((dk) -> {
// String var100001 = secureProperties.getServer().getStoreKey();
// return var100001 + ":" + dk.split(":")[3];
// }).collect(Collectors.toList());
// redisTemplate.delete(ListUtils.sum(beDeleteRefKeys, beDeleteTokenKeys));
// }
// }
//
// public String toString() {
// return "SecureManager()";
// }
//}

View File

@ -0,0 +1,367 @@
package com.bonus.canteen.core.config;
import cn.hutool.core.codec.Base64Decoder;
import com.google.common.collect.Sets;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import java.util.Set;
@RefreshScope
@Component
@ConfigurationProperties(
prefix = "secure"
)
public class SecureProperties {
public static final String PREFIX = "secure";
private boolean enabled = true;
private boolean prohibitUnannotatedHandler = false;
private String tokenSymbol = "X-Token";
private String permissionKey = "secure:pms";
private long permissionTTL = 7200L;
private long expireAfter = 7200L;
private ServerStore server = new ServerStore();
private Security security = new Security();
private MdcLogParameter mdc = new MdcLogParameter();
public boolean isEnabled() {
return this.enabled;
}
public boolean isProhibitUnannotatedHandler() {
return this.prohibitUnannotatedHandler;
}
public String getTokenSymbol() {
return this.tokenSymbol;
}
public String getPermissionKey() {
return this.permissionKey;
}
public long getPermissionTTL() {
return this.permissionTTL;
}
public long getExpireAfter() {
return this.expireAfter;
}
public ServerStore getServer() {
return this.server;
}
public Security getSecurity() {
return this.security;
}
public MdcLogParameter getMdc() {
return this.mdc;
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
public void setProhibitUnannotatedHandler(final boolean prohibitUnannotatedHandler) {
this.prohibitUnannotatedHandler = prohibitUnannotatedHandler;
}
public void setTokenSymbol(final String tokenSymbol) {
this.tokenSymbol = tokenSymbol;
}
public void setPermissionKey(final String permissionKey) {
this.permissionKey = permissionKey;
}
public void setPermissionTTL(final long permissionTTL) {
this.permissionTTL = permissionTTL;
}
public void setExpireAfter(final long expireAfter) {
this.expireAfter = expireAfter;
}
public void setServer(final ServerStore server) {
this.server = server;
}
public void setSecurity(final Security security) {
this.security = security;
}
public void setMdc(final MdcLogParameter mdc) {
this.mdc = mdc;
}
public static class ServerStore {
private String storeKey = "secure:token";
private String subjectRefTokenKey = "secure:subject-token";
private long ttl = 14400L;
public String getStoreKey() {
return this.storeKey;
}
public String getSubjectRefTokenKey() {
return this.subjectRefTokenKey;
}
public long getTtl() {
return this.ttl;
}
public void setStoreKey(final String storeKey) {
this.storeKey = storeKey;
}
public void setSubjectRefTokenKey(final String subjectRefTokenKey) {
this.subjectRefTokenKey = subjectRefTokenKey;
}
public void setTtl(final long ttl) {
this.ttl = ttl;
}
}
public static class Security {
private String encryptUriPrefix = "/security";
private String keyExchangePath = "/exchange/key";
private String publicKeyExchangePath = "/exchange/public-key";
private Set<String> ignoredUri = Sets.newHashSet();
private String requestBodySignParamName = "body";
private String clientKeySignParamName = "clientKey";
private Set<String> addonSignHeaderPrefix = Sets.newHashSet(new String[]{"X-Security-Ext"});
private Set<String> tokenHeaderNames = Sets.newHashSet(new String[]{"X-Security-Token", "X-Security-Tenant-Id", "X-Security-Sn"});
private String tokenSignHeaderName = "X-Security-Token-Sign";
private String serverKeySignParamName = "serverKey";
private String serverSm4Key = "McaCOPft5/J3bUG4pdVjhg==";
private byte[] serverSm4KeyBytes;
private String serverSm2Key;
private byte[] serverSm2KeyBytes;
private String clientSm2Key;
private byte[] clientSm2KeyBytes;
private String timestampHeaderName;
private String nonceHeaderName;
private String signHeaderName;
private String serverEncryptedClientKeyHeaderName;
private long maxWindowSeconds;
private String playKey;
public void setServerSm4Key(String serverSm4Key) {
this.serverSm4Key = serverSm4Key;
this.serverSm4KeyBytes = Base64Decoder.decode(serverSm4Key);
}
public Security() {
this.serverSm4KeyBytes = Base64Decoder.decode(this.serverSm4Key);
this.serverSm2Key = "D55F4709BE51FCDC71D6385885A5CAEE70A09438F862BEB4E56F64A70C76EF5F";
this.serverSm2KeyBytes = Base64Decoder.decode(this.serverSm2Key);
this.clientSm2Key = "04768E8E44656FFD4BA58C0270002A28365A5F6B0F6D40E88B9221CDFAAA8E82C8CCEDBA5FC2D03F20B11492EBE90CC04782682AFE326363A503F086C04A14092C";
this.clientSm2KeyBytes = Base64Decoder.decode(this.serverSm2Key);
this.timestampHeaderName = "X-Security-Timestamp";
this.nonceHeaderName = "X-Security-Nonce";
this.signHeaderName = "X-Security-Sign";
this.serverEncryptedClientKeyHeaderName = "X-Security-Server-Encrypted-Client-Key";
this.maxWindowSeconds = 90L;
this.playKey = "__play:";
}
public String getEncryptUriPrefix() {
return this.encryptUriPrefix;
}
public String getKeyExchangePath() {
return this.keyExchangePath;
}
public String getPublicKeyExchangePath() {
return this.publicKeyExchangePath;
}
public Set<String> getIgnoredUri() {
return this.ignoredUri;
}
public String getRequestBodySignParamName() {
return this.requestBodySignParamName;
}
public String getClientKeySignParamName() {
return this.clientKeySignParamName;
}
public Set<String> getAddonSignHeaderPrefix() {
return this.addonSignHeaderPrefix;
}
public Set<String> getTokenHeaderNames() {
return this.tokenHeaderNames;
}
public String getTokenSignHeaderName() {
return this.tokenSignHeaderName;
}
public String getServerKeySignParamName() {
return this.serverKeySignParamName;
}
public String getServerSm4Key() {
return this.serverSm4Key;
}
public byte[] getServerSm4KeyBytes() {
return this.serverSm4KeyBytes;
}
public String getServerSm2Key() {
return this.serverSm2Key;
}
public byte[] getServerSm2KeyBytes() {
return this.serverSm2KeyBytes;
}
public String getClientSm2Key() {
return this.clientSm2Key;
}
public byte[] getClientSm2KeyBytes() {
return this.clientSm2KeyBytes;
}
public String getTimestampHeaderName() {
return this.timestampHeaderName;
}
public String getNonceHeaderName() {
return this.nonceHeaderName;
}
public String getSignHeaderName() {
return this.signHeaderName;
}
public String getServerEncryptedClientKeyHeaderName() {
return this.serverEncryptedClientKeyHeaderName;
}
public long getMaxWindowSeconds() {
return this.maxWindowSeconds;
}
public String getPlayKey() {
return this.playKey;
}
public void setEncryptUriPrefix(final String encryptUriPrefix) {
this.encryptUriPrefix = encryptUriPrefix;
}
public void setKeyExchangePath(final String keyExchangePath) {
this.keyExchangePath = keyExchangePath;
}
public void setPublicKeyExchangePath(final String publicKeyExchangePath) {
this.publicKeyExchangePath = publicKeyExchangePath;
}
public void setIgnoredUri(final Set<String> ignoredUri) {
this.ignoredUri = ignoredUri;
}
public void setRequestBodySignParamName(final String requestBodySignParamName) {
this.requestBodySignParamName = requestBodySignParamName;
}
public void setClientKeySignParamName(final String clientKeySignParamName) {
this.clientKeySignParamName = clientKeySignParamName;
}
public void setAddonSignHeaderPrefix(final Set<String> addonSignHeaderPrefix) {
this.addonSignHeaderPrefix = addonSignHeaderPrefix;
}
public void setTokenHeaderNames(final Set<String> tokenHeaderNames) {
this.tokenHeaderNames = tokenHeaderNames;
}
public void setTokenSignHeaderName(final String tokenSignHeaderName) {
this.tokenSignHeaderName = tokenSignHeaderName;
}
public void setServerKeySignParamName(final String serverKeySignParamName) {
this.serverKeySignParamName = serverKeySignParamName;
}
public void setServerSm4KeyBytes(final byte[] serverSm4KeyBytes) {
this.serverSm4KeyBytes = serverSm4KeyBytes;
}
public void setServerSm2Key(final String serverSm2Key) {
this.serverSm2Key = serverSm2Key;
}
public void setServerSm2KeyBytes(final byte[] serverSm2KeyBytes) {
this.serverSm2KeyBytes = serverSm2KeyBytes;
}
public void setClientSm2Key(final String clientSm2Key) {
this.clientSm2Key = clientSm2Key;
}
public void setClientSm2KeyBytes(final byte[] clientSm2KeyBytes) {
this.clientSm2KeyBytes = clientSm2KeyBytes;
}
public void setTimestampHeaderName(final String timestampHeaderName) {
this.timestampHeaderName = timestampHeaderName;
}
public void setNonceHeaderName(final String nonceHeaderName) {
this.nonceHeaderName = nonceHeaderName;
}
public void setSignHeaderName(final String signHeaderName) {
this.signHeaderName = signHeaderName;
}
public void setServerEncryptedClientKeyHeaderName(final String serverEncryptedClientKeyHeaderName) {
this.serverEncryptedClientKeyHeaderName = serverEncryptedClientKeyHeaderName;
}
public void setMaxWindowSeconds(final long maxWindowSeconds) {
this.maxWindowSeconds = maxWindowSeconds;
}
public void setPlayKey(final String playKey) {
this.playKey = playKey;
}
}
public static class MdcLogParameter {
private String subjectId = "x-id";
private String subjectName = "x-name";
public String getSubjectId() {
return this.subjectId;
}
public String getSubjectName() {
return this.subjectName;
}
public void setSubjectId(final String subjectId) {
this.subjectId = subjectId;
}
public void setSubjectName(final String subjectName) {
this.subjectName = subjectName;
}
}
}

View File

@ -0,0 +1,126 @@
package com.bonus.canteen.core.config;
import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.util.PrimitiveArrayUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.symmetric.SM4;
import com.bonus.canteen.core.common.utils.SpringContextHolder;
import com.google.common.base.Joiner;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.SortedMap;
public class SmUtils {
private static final Logger log = LoggerFactory.getLogger(SmUtils.class);
private static SecureProperties secureProperties = SpringContextHolder.getBean(SecureProperties.class);
public static void setSecureProperties(SecureProperties secureProperties) {
if (SmUtils.secureProperties == null) {
SmUtils.secureProperties = secureProperties;
}
}
public static String signBySm3(SortedMap<String, String> data, String clientKey) {
data.put(secureProperties.getSecurity().getClientKeySignParamName(), clientKey);
String joinedParam = Joiner.on("&").useForNull("").withKeyValueSeparator("=").join(data);
log.debug("Sign param:{}", joinedParam);
return Base64Encoder.encode(SmUtil.sm3().digest(joinedParam));
}
public static String signBySm3WithServerKey(SortedMap<String, String> data, String clientKey) {
data.put(secureProperties.getSecurity().getServerKeySignParamName(), secureProperties.getSecurity().getServerSm4Key());
return signBySm3(data, clientKey);
}
public static String signAuthTokenBySm3(SortedMap<String, String> data, String clientKey) {
return signBySm3WithServerKey(data, clientKey);
}
public static String decryptBySm2(String data) {
return SmUtil.sm2(secureProperties.getSecurity().getServerSm2Key(), secureProperties.getSecurity().getClientSm2Key()).decryptStr(data, KeyType.PrivateKey);
}
public static String signBySm2(String data) {
return Base64Encoder.encode(SmUtil.sm2(secureProperties.getSecurity().getServerSm2Key(), secureProperties.getSecurity().getClientSm2Key()).sign(data.getBytes(StandardCharsets.UTF_8)));
}
public static String decryptBySm4(String data, byte[] key) {
byte[] decodedData = Base64Decoder.decode(data);
if (decodedData.length <= 16) {
throw new IllegalArgumentException("Encrypted data byte length must greater than 16");
} else {
byte[] iv = PrimitiveArrayUtil.sub(decodedData, 0, 16);
byte[] dataBytes = PrimitiveArrayUtil.sub(decodedData, 16, decodedData.length);
return (new SM4(Mode.CBC, Padding.PKCS5Padding, key, iv)).decryptStr(dataBytes);
}
}
public static String decryptBySm4(String data, String key) {
return decryptBySm4(data, Base64Decoder.decode(key));
}
public static String decryptBySm4WithServerKey(String data) {
return decryptBySm4(data, secureProperties.getSecurity().getServerSm4KeyBytes());
}
public static String encryptBySm4(String data, byte[] key) {
SM4 var10000 = new SM4(Mode.CBC, Padding.PKCS5Padding, key, RandomUtil.randomBytes(16));
String var10001 = RandomUtil.randomString(16);
return var10000.encryptBase64(var10001 + data);
}
public static String encryptBySm4WithServerKey(String data) {
return encryptBySm4(data, secureProperties.getSecurity().getServerSm4KeyBytes());
}
public static void main(String[] args) throws NoSuchAlgorithmException {
//sm2() 移到 SmUtilsTest.java
sm4();
sm4WithoutIV();
}
private static void sm4() throws NoSuchAlgorithmException {
System.out.println("================sm4==================");
BouncyCastleProvider provider = new BouncyCastleProvider();
KeyGenerator generator = KeyGenerator.getInstance("SM4", provider);
SecretKey secretKey = generator.generateKey();
byte[] encoded = secretKey.getEncoded();
String key = Base64Encoder.encode(encoded);
System.out.println("key: " + key);
String data = "liolay";
String encryptBySm4 = encryptBySm4(data, encoded);
System.out.println("encrypt: " + encryptBySm4);
PrintStream var10000 = System.out;
String var10001 = decryptBySm4(encryptBySm4, encoded);
var10000.println("decrypt: " + var10001);
var10000 = System.out;
var10001 = decryptBySm4(encryptBySm4, key);
var10000.println("decrypt: " + var10001);
}
private static void sm4WithoutIV() throws NoSuchAlgorithmException {
System.out.println("================sm4WithoutIV==================");
BouncyCastleProvider provider = new BouncyCastleProvider();
KeyGenerator generator = KeyGenerator.getInstance("SM4", provider);
SecretKey secretKey = generator.generateKey();
byte[] key = secretKey.getEncoded();
String keyEncode = Base64Encoder.encode(key);
System.out.println("key: " + keyEncode);
String plainData = "liolay";
String encryptedData = encryptBySm4(plainData, key);
System.out.println("encrypt: " + encryptedData);
String decryptData = decryptBySm4(encryptedData, key);
System.out.println("decrypt: " + decryptData);
}
}

View File

@ -0,0 +1,102 @@
package com.bonus.canteen.core.config;
import com.google.common.collect.Maps;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Optional;
public class WebContext {
private static final ThreadLocal<Context> THREAD_CONTEXT = new InheritableThreadLocal<Context>() {
@Override
protected Context initialValue() {
return new Context();
}
};
private WebContext() {
}
public static void reset() {
THREAD_CONTEXT.remove();
}
public static Context get() {
return (Context)THREAD_CONTEXT.get();
}
public static void set(Context context) {
THREAD_CONTEXT.set(context);
}
public static class Context {
private HttpServletRequest request;
private HttpServletResponse response;
private AccessToken accessToken;
private Map<String, Object> attributes = Maps.newHashMap();
public Context(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
}
public void setAttribute(String key, Object data) {
this.attributes.put(key, data);
}
public Object getAttribute(String key) {
return this.attributes.get(key);
}
public void removeAttribute(String key) {
this.attributes.remove(key);
}
public void clearAttribute() {
this.attributes.clear();
}
public Optional<AccessToken> getAccessToken() {
return Optional.ofNullable(this.accessToken);
}
public Optional<HttpServletRequest> getRequest() {
return Optional.ofNullable(this.request);
}
public Optional<HttpServletResponse> getResponse() {
return Optional.ofNullable(this.response);
}
public Map<String, Object> getAttributes() {
return this.attributes;
}
public void setRequest(final HttpServletRequest request) {
this.request = request;
}
public void setResponse(final HttpServletResponse response) {
this.response = response;
}
public void setAccessToken(final AccessToken accessToken) {
this.accessToken = accessToken;
}
public void setAttributes(final Map<String, Object> attributes) {
this.attributes = attributes;
}
public Context() {
}
public Context(final HttpServletRequest request, final HttpServletResponse response, final AccessToken accessToken, final Map<String, Object> attributes) {
this.request = request;
this.response = response;
this.accessToken = accessToken;
this.attributes = attributes;
}
}
}

View File

@ -0,0 +1,11 @@
package com.bonus.canteen.core.config.json;
import com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializer;
import java.time.format.DateTimeFormatter;
public class InstantsSerializer extends InstantSerializer {
public InstantsSerializer(DateTimeFormatter defaultFormat) {
super(InstantSerializer.INSTANCE, false, defaultFormat);
}
}

View File

@ -0,0 +1,78 @@
package com.bonus.canteen.core.config.json;
import com.bonus.canteen.core.config.WebContext;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.datatype.jsr310.PackageVersion;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.TimeZone;
//@AutoConfiguration(
// before = {JacksonAutoConfiguration.class}
//)
@Configuration
//@ConditionalOnClass({ObjectMapper.class})
public class JacksonConfiguration {
public static final StdSerializer<Long> LONG_STD_SERIALIZER;
@Bean
Jackson2ObjectMapperBuilderCustomizer objectMapperBuilderCustomizer() {
return (builder) -> {
builder.serializerByType(Long.TYPE, LONG_STD_SERIALIZER);
builder.serializerByType(Long.class, LONG_STD_SERIALIZER);
builder.locale(Locale.CHINA);
builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
builder.modules(new Module[]{new SimpleModule(PackageVersion.VERSION) {
{
this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
this.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
this.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
this.addSerializer(Instant.class, new InstantsSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
this.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
this.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
}
}});
};
}
static {
LONG_STD_SERIALIZER = new StdSerializer<Long>(Long.TYPE) {
@Override
public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (value == null) {
jsonGenerator.writeNull();
} else {
Optional<HttpServletRequest> requestOptional = WebContext.get().getRequest();
if ((Boolean)requestOptional.map((request) -> {
return Objects.isNull(request.getHeader("User-Agent")) || request.getHeader("User-Agent").contains("okhttp");
}).orElse(false)) {
jsonGenerator.writeNumber(value);
} else {
jsonGenerator.writeString(value.toString());
}
}
}
};
}
}

View File

@ -0,0 +1,57 @@
package com.bonus.canteen.core.config.json;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@MappedTypes({JsonNode.class})
public class JsonNodeTypeHandler extends BaseTypeHandler<JsonNode> {
private static final Logger log = LoggerFactory.getLogger(JsonNodeTypeHandler.class);
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, JsonNode jsonNode, JdbcType jdbcType) throws SQLException {
preparedStatement.setString(i, jsonNode.toString());
}
private JsonNode read(String json) {
if (json != null && !json.isEmpty()) {
try {
return this.objectMapper.readTree(json);
} catch (JsonProcessingException var3) {
log.warn("JSON parse failed", var3);
return null;
}
} else {
return null;
}
}
@Override
public JsonNode getNullableResult(ResultSet rs, String columnName) throws SQLException {
String json = rs.getString(columnName);
return this.read(json);
}
@Override
public JsonNode getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String json = rs.getString(columnIndex);
return this.read(json);
}
@Override
public JsonNode getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String json = cs.getString(columnIndex);
return this.read(json);
}
}