mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-11 20:25:12 +00:00
(improvement)(auth) Fix the issue of a too short key. (#1207)
This commit is contained in:
@@ -1,12 +1,13 @@
|
|||||||
package com.tencent.supersonic.auth.api.authentication.config;
|
package com.tencent.supersonic.auth.api.authentication.config;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -24,7 +25,8 @@ public class AuthenticationConfig {
|
|||||||
@Value("${authentication.token.default.appKey:supersonic}")
|
@Value("${authentication.token.default.appKey:supersonic}")
|
||||||
private String tokenDefaultAppKey;
|
private String tokenDefaultAppKey;
|
||||||
|
|
||||||
@Value("${authentication.token.appSecret:supersonic:secret}")
|
@Value("${authentication.token.appSecret:supersonic:WIaO9YRRVt+7QtpPvyWsARFngnEcbaKBk"
|
||||||
|
+ "783uGFwMrbJBaochsqCH62L4Kijcb0sZCYoSsiKGV/zPml5MnZ3uQ==}")
|
||||||
private String tokenAppSecret;
|
private String tokenAppSecret;
|
||||||
|
|
||||||
@Value("${authentication.token.http.header.key:Authorization}")
|
@Value("${authentication.token.http.header.key:Authorization}")
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ import com.tencent.supersonic.auth.authentication.persistence.repository.UserRep
|
|||||||
import com.tencent.supersonic.auth.authentication.utils.AESEncryptionUtil;
|
import com.tencent.supersonic.auth.authentication.utils.AESEncryptionUtil;
|
||||||
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
||||||
import com.tencent.supersonic.common.util.ContextUtils;
|
import com.tencent.supersonic.common.util.ContextUtils;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -94,6 +95,7 @@ public class DefaultUserAdaptor implements UserAdaptor {
|
|||||||
UserWithPassword user = getUserWithPassword(userReq);
|
UserWithPassword user = getUserWithPassword(userReq);
|
||||||
return userTokenUtils.generateToken(user, request);
|
return userTokenUtils.generateToken(user, request);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
log.error("", e);
|
||||||
throw new RuntimeException("password encrypt error, please try again");
|
throw new RuntimeException("password encrypt error, please try again");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
package com.tencent.supersonic.auth.authentication.utils;
|
package com.tencent.supersonic.auth.authentication.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.SecretKeyFactory;
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.spec.KeySpec;
|
import java.security.spec.KeySpec;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class AESEncryptionUtil {
|
public class AESEncryptionUtil {
|
||||||
|
|
||||||
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
|
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
|
||||||
@@ -28,24 +31,29 @@ public class AESEncryptionUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String encrypt(String password, byte[] salt) throws Exception {
|
public static String encrypt(String password, byte[] salt) throws Exception {
|
||||||
// TODO 固定IV,确保每次加密时使用相同的IV,该值应该安全保管
|
try {
|
||||||
byte[] iv = "supersonic@bicom".getBytes(ENCODE);
|
// TODO 固定IV,确保每次加密时使用相同的IV,该值应该安全保管
|
||||||
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
|
byte[] iv = "supersonic@bicom".getBytes(ENCODE);
|
||||||
|
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
|
||||||
|
|
||||||
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH);
|
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH);
|
||||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM);
|
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM);
|
||||||
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
|
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
|
||||||
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
|
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
|
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
|
||||||
|
|
||||||
byte[] encrypted = cipher.doFinal(password.getBytes(ENCODE));
|
byte[] encrypted = cipher.doFinal(password.getBytes(ENCODE));
|
||||||
byte[] combined = new byte[iv.length + encrypted.length];
|
byte[] combined = new byte[iv.length + encrypted.length];
|
||||||
System.arraycopy(iv, 0, combined, 0, iv.length);
|
System.arraycopy(iv, 0, combined, 0, iv.length);
|
||||||
System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);
|
System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);
|
||||||
|
|
||||||
return Base64.getEncoder().encodeToString(combined);
|
return Base64.getEncoder().encodeToString(combined);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error("encrypt", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getStringFromBytes(byte[] salt) {
|
public static String getStringFromBytes(byte[] salt) {
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_ALGORITHM;
|
|
||||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_CREATE_TIME;
|
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_CREATE_TIME;
|
||||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_IS_ADMIN;
|
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_IS_ADMIN;
|
||||||
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_PREFIX;
|
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_PREFIX;
|
||||||
@@ -122,6 +122,7 @@ public class UserTokenUtils {
|
|||||||
.setSigningKey(tokenSecret.getBytes(StandardCharsets.UTF_8))
|
.setSigningKey(tokenSecret.getBytes(StandardCharsets.UTF_8))
|
||||||
.build().parseClaimsJws(getTokenString(token)).getBody();
|
.build().parseClaimsJws(getTokenString(token)).getBody();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
log.error("getClaims", e);
|
||||||
throw new AccessException("parse user info from token failed :" + token);
|
throw new AccessException("parse user info from token failed :" + token);
|
||||||
}
|
}
|
||||||
return claims;
|
return claims;
|
||||||
@@ -143,13 +144,12 @@ public class UserTokenUtils {
|
|||||||
Date expirationDate = new Date(expiration);
|
Date expirationDate = new Date(expiration);
|
||||||
String tokenSecret = getTokenSecret(appKey);
|
String tokenSecret = getTokenSecret(appKey);
|
||||||
|
|
||||||
SignatureAlgorithm.valueOf(TOKEN_ALGORITHM);
|
|
||||||
return Jwts.builder()
|
return Jwts.builder()
|
||||||
.setClaims(claims)
|
.setClaims(claims)
|
||||||
.setSubject(claims.get(TOKEN_USER_NAME).toString())
|
.setSubject(claims.get(TOKEN_USER_NAME).toString())
|
||||||
.setExpiration(expirationDate)
|
.setExpiration(expirationDate)
|
||||||
.signWith(SignatureAlgorithm.valueOf(TOKEN_ALGORITHM),
|
.signWith(new SecretKeySpec(tokenSecret.getBytes(StandardCharsets.UTF_8),
|
||||||
tokenSecret.getBytes(StandardCharsets.UTF_8))
|
SignatureAlgorithm.HS512.getJcaName()), SignatureAlgorithm.HS512)
|
||||||
.compact();
|
.compact();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.assertj.core.util.Lists;
|
|||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
class DateUtilsTest {
|
class DateUtilsTest {
|
||||||
|
|||||||
Reference in New Issue
Block a user