init: UserBaseService (backend + deploy + scripts)
ci-userbase-service / build-and-push (push) Successful in 40s
ci-userbase-service / build-and-push (push) Successful in 40s
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
package com.yunhai.userbase.config;
|
||||
|
||||
import com.yunhai.platform.appauth.AppAuthProperties;
|
||||
import com.yunhai.platform.appauth.AppSecretProvider;
|
||||
import com.yunhai.userbase.entity.ApplicationInfo;
|
||||
import com.yunhai.userbase.repository.ApplicationInfoRepository;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* UserBase 作为「应用密钥权威源」的验签密钥提供方。<br><br>
|
||||
* 解析优先级:<br>
|
||||
* 1) 本库 application_info —— 覆盖全部「已颁发」应用,新增/重置密钥后即时生效;<br>
|
||||
* 2) 配置式受信应用 {@code yh.app-auth.trusted-apps} —— 平台自身默认密钥(如 应用中心 100616)
|
||||
* 兜底,使其即便尚未落库也可验签,避免「默认 appKey 未建行」导致验签失败。<br><br>
|
||||
* 带 60s 本地 TTL 缓存,避免每次验签直打库(密钥变更最长 60s 后生效)。<br><br>
|
||||
* 这样 UserBase 作为颁发方不依赖 Redis 预热、也不局限于 trustedApps 写死的少量密钥,
|
||||
* 能够验签所有它已颁发的应用。
|
||||
*/
|
||||
public class UserBaseAppSecretProvider implements AppSecretProvider {
|
||||
|
||||
private final ApplicationInfoRepository repository;
|
||||
private final Map<String, String> trustedApps;
|
||||
private final ConcurrentHashMap<String, CacheEntry> cache = new ConcurrentHashMap<>();
|
||||
private static final long TTL_MS = 60_000L;
|
||||
|
||||
public UserBaseAppSecretProvider(ApplicationInfoRepository repository, AppAuthProperties properties) {
|
||||
this.repository = repository;
|
||||
this.trustedApps = properties.getTrustedApps();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSecret(String appKey) {
|
||||
if (appKey == null) {
|
||||
return null;
|
||||
}
|
||||
long now = System.currentTimeMillis();
|
||||
CacheEntry hit = cache.get(appKey);
|
||||
if (hit != null && now - hit.ts < TTL_MS) {
|
||||
return hit.secret;
|
||||
}
|
||||
String secret = null;
|
||||
try {
|
||||
Integer id = parse(appKey);
|
||||
if (id != null) {
|
||||
ApplicationInfo info = repository.findByAppKey(id);
|
||||
if (info != null && info.getAppSecret() != null && !info.getAppSecret().trim().isEmpty()) {
|
||||
secret = info.getAppSecret();
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 查询异常不阻断,继续走配置兜底
|
||||
}
|
||||
if (secret == null) {
|
||||
secret = trustedApps.get(appKey);
|
||||
}
|
||||
cache.put(appKey, new CacheEntry(now, secret));
|
||||
return secret;
|
||||
}
|
||||
|
||||
private static Integer parse(String appKey) {
|
||||
try {
|
||||
return Integer.parseInt(appKey.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CacheEntry {
|
||||
final long ts;
|
||||
final String secret;
|
||||
|
||||
CacheEntry(long ts, String secret) {
|
||||
this.ts = ts;
|
||||
this.secret = secret;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user