From 76208975bffec39eb62f8599a68d583a5cb6da18 Mon Sep 17 00:00:00 2001 From: leesam <leesam@leesam.cn> Date: 星期二, 19 三月 2024 16:53:01 +0800 Subject: [PATCH] [add]支持其他平台通过ApiKey调用系统相关接口 --- src/main/java/com/genersoft/iot/vmp/conf/security/JwtUtils.java | 106 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 90 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/conf/security/JwtUtils.java b/src/main/java/com/genersoft/iot/vmp/conf/security/JwtUtils.java index fcd1946..949bcba 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/security/JwtUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/security/JwtUtils.java @@ -1,8 +1,12 @@ package com.genersoft.iot.vmp.conf.security; import com.genersoft.iot.vmp.conf.security.dto.JwtUser; +import com.genersoft.iot.vmp.service.IUserApiKeyService; import com.genersoft.iot.vmp.service.IUserService; import com.genersoft.iot.vmp.storager.dao.dto.User; +import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey; +import org.jose4j.jwk.JsonWebKey; +import org.jose4j.jwk.JsonWebKeySet; import org.jose4j.jwk.RsaJsonWebKey; import org.jose4j.jwk.RsaJwkGenerator; import org.jose4j.jws.AlgorithmIdentifiers; @@ -20,8 +24,18 @@ import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.time.LocalDateTime; import java.time.ZoneOffset; +import java.util.List; +import java.util.Map; @Component public class JwtUtils implements InitializingBean { @@ -30,6 +44,8 @@ public static final String HEADER = "access-token"; + public static final String API_KEY_HEADER = "api-key"; + private static final String AUDIENCE = "Audience"; private static final String keyId = "3e79646c4dbc408383a9eed09f2b85ae"; @@ -37,15 +53,26 @@ /** * token杩囨湡鏃堕棿(鍒嗛挓) */ - public static final long expirationTime = 30 * 24 * 60; + public static final long EXPIRATION_TIME = 30 * 24 * 60; private static RsaJsonWebKey rsaJsonWebKey; private static IUserService userService; + private static IUserApiKeyService userApiKeyService; + + public static String getApiKeyHeader() { + return API_KEY_HEADER; + } + @Resource public void setUserService(IUserService userService) { JwtUtils.userService = userService; + } + + @Resource + public void setUserApiKeyService(IUserApiKeyService userApiKeyService) { + JwtUtils.userApiKeyService = userApiKeyService; } @Override @@ -62,14 +89,38 @@ * @throws JoseException JoseException */ private RsaJsonWebKey generateRsaJsonWebKey() throws JoseException { - // 鐢熸垚涓�涓猂SA瀵嗛挜瀵癸紝璇ュ瘑閽ュ灏嗙敤浜嶫WT鐨勭鍚嶅拰楠岃瘉锛屽寘瑁呭湪JWK涓� - RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048); - // 缁橨WK涓�涓瘑閽D - rsaJsonWebKey.setKeyId(keyId); + RsaJsonWebKey rsaJsonWebKey = null; + try { + URL url = getClass().getClassLoader().getResource("jwk.json"); + if (url != null) { + URI uri = url.toURI(); + Path path = Paths.get(uri); + if (Files.exists(path)) { + byte[] allBytes = Files.readAllBytes(path); + String jwkJson = new String(allBytes, StandardCharsets.UTF_8); + final JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(jwkJson); + List<JsonWebKey> jsonWebKeys = jsonWebKeySet.getJsonWebKeys(); + if (!jsonWebKeys.isEmpty()) { + JsonWebKey jsonWebKey = jsonWebKeys.get(0); + if (jsonWebKey instanceof RsaJsonWebKey) { + rsaJsonWebKey = (RsaJsonWebKey) jsonWebKey; + } + } + } + } + } catch (URISyntaxException | IOException e) { + // ignored + } + if (rsaJsonWebKey == null) { + // 鐢熸垚涓�涓猂SA瀵嗛挜瀵癸紝璇ュ瘑閽ュ灏嗙敤浜嶫WT鐨勭鍚嶅拰楠岃瘉锛屽寘瑁呭湪JWK涓� + rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048); + // 缁橨WK涓�涓瘑閽D + rsaJsonWebKey.setKeyId(keyId); + } return rsaJsonWebKey; } - public static String createToken(String username) { + public static String createToken(String username, Long expirationTime, Map<String, Object> extra) { try { /* * 鈥渋ss鈥� (issuer) 鍙戣浜� @@ -83,13 +134,17 @@ claims.setGeneratedJwtId(); claims.setIssuedAtToNow(); // 浠ょ墝灏嗚繃鏈熺殑鏃堕棿 鍒嗛挓 - claims.setExpirationTimeMinutesInTheFuture(expirationTime); + if (expirationTime != null) { + claims.setExpirationTimeMinutesInTheFuture(expirationTime); + } claims.setNotBeforeMinutesInThePast(0); claims.setSubject("login"); claims.setAudience(AUDIENCE); //娣诲姞鑷畾涔夊弬鏁�,蹇呴』鏄瓧绗︿覆绫诲瀷 claims.setClaim("userName", username); - + if (extra != null) { + extra.forEach(claims::setClaim); + } //jws JsonWebSignature jws = new JsonWebSignature(); //绛惧悕绠楁硶RS256 @@ -104,8 +159,15 @@ } catch (JoseException e) { logger.error("[Token鐢熸垚澶辫触]锛� {}", e.getMessage()); } - return null; + } + + public static String createToken(String username, Long expirationTime) { + return createToken(username, expirationTime, null); + } + + public static String createToken(String username) { + return createToken(username, EXPIRATION_TIME); } public static String getHeader() { @@ -118,8 +180,8 @@ try { JwtConsumer consumer = new JwtConsumerBuilder() - .setRequireExpirationTime() - .setMaxFutureValidityInMinutes(5256000) + //.setRequireExpirationTime() + //.setMaxFutureValidityInMinutes(5256000) .setAllowedClockSkewInSeconds(30) .setRequireSubject() //.setExpectedIssuer("") @@ -129,15 +191,27 @@ JwtClaims claims = consumer.processToClaims(token); NumericDate expirationTime = claims.getExpirationTime(); - // 鍒ゆ柇鏄惁鍗冲皢杩囨湡, 榛樿鍓╀綑鏃堕棿灏忎簬5鍒嗛挓鏈嵆灏嗚繃鏈� - // 鍓╀綑鏃堕棿 锛堢锛� - long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue(); - if (timeRemaining < 5 * 60) { - jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON); + if (expirationTime != null) { + // 鍒ゆ柇鏄惁鍗冲皢杩囨湡, 榛樿鍓╀綑鏃堕棿灏忎簬5鍒嗛挓鏈嵆灏嗚繃鏈� + // 鍓╀綑鏃堕棿 锛堢锛� + long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue(); + if (timeRemaining < 5 * 60) { + jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON); + } else { + jwtUser.setStatus(JwtUser.TokenStatus.NORMAL); + } } else { jwtUser.setStatus(JwtUser.TokenStatus.NORMAL); } + Long apiKeyId = claims.getClaimValue("apiKeyId", Long.class); + if (apiKeyId != null) { + UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(apiKeyId.intValue()); + if (userApiKey == null || !userApiKey.isEnable()) { + jwtUser.setStatus(JwtUser.TokenStatus.EXPIRED); + } + } + String username = (String) claims.getClaimValue("userName"); User user = userService.getUserByUsername(username); -- Gitblit v1.8.0