mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-11 03:58:14 +00:00
@@ -9,6 +9,7 @@ import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
|
||||
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
|
||||
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
|
||||
import com.tencent.supersonic.auth.authentication.persistence.repository.UserRepository;
|
||||
import com.tencent.supersonic.auth.authentication.utils.AESEncryptionUtil;
|
||||
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@@ -72,6 +73,14 @@ public class DefaultUserAdaptor implements UserAdaptor {
|
||||
}
|
||||
UserDO userDO = new UserDO();
|
||||
BeanUtils.copyProperties(userReq, userDO);
|
||||
try {
|
||||
byte[] salt = AESEncryptionUtil.generateSalt(userDO.getName());
|
||||
userDO.setSalt(AESEncryptionUtil.getStringFromBytes(salt));
|
||||
System.out.println("salt: " + userDO.getSalt());
|
||||
userDO.setPassword(AESEncryptionUtil.encrypt(userReq.getPassword(), salt));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("password encrypt error, please try again");
|
||||
}
|
||||
userRepository.addUser(userDO);
|
||||
}
|
||||
|
||||
@@ -82,12 +91,24 @@ public class DefaultUserAdaptor implements UserAdaptor {
|
||||
if (userDO == null) {
|
||||
throw new RuntimeException("user not exist,please register");
|
||||
}
|
||||
if (userDO.getPassword().equals(userReq.getPassword())) {
|
||||
UserWithPassword user = UserWithPassword.get(userDO.getId(), userDO.getName(), userDO.getDisplayName(),
|
||||
userDO.getEmail(), userDO.getPassword(), userDO.getIsAdmin());
|
||||
return userTokenUtils.generateToken(user);
|
||||
|
||||
try {
|
||||
String password = AESEncryptionUtil.encrypt(userReq.getPassword(),
|
||||
AESEncryptionUtil.getBytesFromString(userDO.getSalt()));
|
||||
System.out.println("userReq.getPassword(): " + userReq.getPassword());
|
||||
System.out.println("password: " + password);
|
||||
System.out.println("userDO.getPassword(): " + userDO.getPassword());
|
||||
if (userDO.getPassword().equals(password)) {
|
||||
UserWithPassword user = UserWithPassword.get(userDO.getId(), userDO.getName(), userDO.getDisplayName(),
|
||||
userDO.getEmail(), userDO.getPassword(), userDO.getIsAdmin());
|
||||
return userTokenUtils.generateToken(user);
|
||||
} else {
|
||||
throw new RuntimeException("password not correct, please try again");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("password encrypt error, please try again");
|
||||
}
|
||||
throw new RuntimeException("password not correct, please try again");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,8 @@ public class UserDO {
|
||||
*/
|
||||
private String password;
|
||||
|
||||
private String salt;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -79,6 +81,14 @@ public class UserDO {
|
||||
this.password = password == null ? null : password.trim();
|
||||
}
|
||||
|
||||
public String getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public void setSalt(String salt) {
|
||||
this.salt = salt == null ? null : salt.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return display_name
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.tencent.supersonic.auth.authentication.utils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
public class AESEncryptionUtil {
|
||||
|
||||
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
|
||||
private static final String ENCODE = "UTF-8";
|
||||
private static final String SECRET_KEY_ALGORITHM = "PBKDF2WithHmacSHA256";
|
||||
private static final int ITERATIONS = 65536;
|
||||
private static final int KEY_LENGTH = 256;
|
||||
|
||||
public static byte[] generateSalt(String username) throws Exception {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
md.update(username.getBytes(ENCODE));
|
||||
byte[] hash = md.digest();
|
||||
// 通常只需要使用盐的一部分作为盐值,例如16字节
|
||||
byte[] salt = new byte[16];
|
||||
System.arraycopy(hash, 0, salt, 0, salt.length);
|
||||
return salt;
|
||||
}
|
||||
|
||||
public static String encrypt(String password, byte[] salt) throws Exception {
|
||||
// TODO 固定IV,确保每次加密时使用相同的IV,该值应该安全保管
|
||||
byte[] iv = "supersonic@bicom".getBytes(ENCODE);
|
||||
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
|
||||
|
||||
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH);
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM);
|
||||
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
|
||||
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
|
||||
|
||||
byte[] encrypted = cipher.doFinal(password.getBytes(ENCODE));
|
||||
byte[] combined = new byte[iv.length + encrypted.length];
|
||||
System.arraycopy(iv, 0, combined, 0, iv.length);
|
||||
System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);
|
||||
|
||||
return Base64.getEncoder().encodeToString(combined);
|
||||
}
|
||||
|
||||
public static String getStringFromBytes(byte[] salt) {
|
||||
return Base64.getEncoder().encodeToString(salt);
|
||||
}
|
||||
|
||||
public static byte[] getBytesFromString(String encodeSalt) {
|
||||
return Base64.getDecoder().decode(encodeSalt);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
<result column="id" jdbcType="BIGINT" property="id" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="password" jdbcType="VARCHAR" property="password" />
|
||||
<result column="salt" jdbcType="VARCHAR" property="salt" />
|
||||
<result column="display_name" jdbcType="VARCHAR" property="displayName" />
|
||||
<result column="email" jdbcType="VARCHAR" property="email" />
|
||||
<result column="is_admin" jdbcType="INTEGER" property="isAdmin" />
|
||||
@@ -39,7 +40,7 @@
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, name, password, display_name, email, is_admin
|
||||
id, name, password, salt, display_name, email, is_admin
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample" resultMap="BaseResultMap">
|
||||
select
|
||||
@@ -59,10 +60,10 @@
|
||||
</if>
|
||||
</select>
|
||||
<insert id="insert" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
|
||||
insert into s2_user (id, name, password,
|
||||
insert into s2_user (id, name, password, salt,
|
||||
display_name, email, is_admin
|
||||
)
|
||||
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
|
||||
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{salt,jdbcType=VARCHAR},
|
||||
#{displayName,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{isAdmin,jdbcType=INTEGER}
|
||||
)
|
||||
</insert>
|
||||
@@ -78,6 +79,9 @@
|
||||
<if test="password != null">
|
||||
password,
|
||||
</if>
|
||||
<if test="password != null">
|
||||
salt,
|
||||
</if>
|
||||
<if test="displayName != null">
|
||||
display_name,
|
||||
</if>
|
||||
@@ -98,6 +102,9 @@
|
||||
<if test="password != null">
|
||||
#{password,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="salt != null">
|
||||
#{salt,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="displayName != null">
|
||||
#{displayName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
|
||||
Reference in New Issue
Block a user