mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-10 11:07:06 +00:00
(improvement)(auth) Support token key allocation based on the integration application. (#1119)
This commit is contained in:
@@ -6,6 +6,7 @@ import com.tencent.supersonic.auth.api.authentication.request.UserReq;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* UserAdaptor defines some interfaces for obtaining user and organization information
|
||||
@@ -20,7 +21,7 @@ public interface UserAdaptor {
|
||||
|
||||
void register(UserReq userReq);
|
||||
|
||||
String login(UserReq userReq);
|
||||
String login(UserReq userReq, HttpServletRequest request);
|
||||
|
||||
List<User> getUserByOrg(String key);
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.tencent.supersonic.auth.api.authentication.config;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -18,12 +21,18 @@ public class AuthenticationConfig {
|
||||
@Value("${authentication.enable:false}")
|
||||
private boolean enabled;
|
||||
|
||||
@Value("${authentication.token.secret:secret}")
|
||||
private String tokenSecret;
|
||||
@Value("${authentication.token.default.appKey:supersonic}")
|
||||
private String tokenDefaultAppKey;
|
||||
|
||||
@Value("${authentication.token.appSecret:supersonic:secret}")
|
||||
private String tokenAppSecret;
|
||||
|
||||
@Value("${authentication.token.http.header.key:Authorization}")
|
||||
private String tokenHttpHeaderKey;
|
||||
|
||||
@Value("${authentication.token.http.app.key:App-Key}")
|
||||
private String tokenHttpHeaderAppKey;
|
||||
|
||||
@Value("${authentication.app.appId:appId}")
|
||||
private String appId;
|
||||
|
||||
@@ -35,4 +44,10 @@ public class AuthenticationConfig {
|
||||
|
||||
@Value("${authentication.token.timeout:7200000}")
|
||||
private Long tokenTimeout;
|
||||
|
||||
public Map<String, String> getAppKeyToSecretMap() {
|
||||
return Arrays.stream(this.tokenAppSecret.split(","))
|
||||
.map(s -> s.split(":"))
|
||||
.collect(Collectors.toMap(e -> e[0].trim(), e -> e[1].trim()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public interface UserService {
|
||||
|
||||
void register(UserReq userCmd);
|
||||
|
||||
String login(UserReq userCmd);
|
||||
String login(UserReq userCmd, HttpServletRequest request);
|
||||
|
||||
Set<String> getUserAllOrgId(String userName);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.tencent.supersonic.auth.authentication.persistence.repository.UserRep
|
||||
import com.tencent.supersonic.auth.authentication.utils.AESEncryptionUtil;
|
||||
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import java.util.List;
|
||||
@@ -87,7 +88,7 @@ public class DefaultUserAdaptor implements UserAdaptor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String login(UserReq userReq) {
|
||||
public String login(UserReq userReq, HttpServletRequest request) {
|
||||
UserTokenUtils userTokenUtils = ContextUtils.getBean(UserTokenUtils.class);
|
||||
UserDO userDO = getUser(userReq.getName());
|
||||
if (userDO == null) {
|
||||
@@ -100,7 +101,7 @@ public class DefaultUserAdaptor implements UserAdaptor {
|
||||
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);
|
||||
return userTokenUtils.generateToken(user, request);
|
||||
} else {
|
||||
throw new RuntimeException("password not correct, please try again");
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
|
||||
}
|
||||
|
||||
private void setFakerUser(HttpServletRequest request) {
|
||||
String token = userTokenUtils.generateAdminToken();
|
||||
String token = userTokenUtils.generateAdminToken(request);
|
||||
reflectSetparam(request, authenticationConfig.getTokenHttpHeaderKey(), token);
|
||||
setContext(User.getFakeUser().getName(), request);
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ public class UserController {
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
public String login(@RequestBody UserReq userCmd) {
|
||||
return userService.login(userCmd);
|
||||
public String login(@RequestBody UserReq userCmd, HttpServletRequest request) {
|
||||
return userService.login(userCmd, request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ public class UserServiceImpl implements UserService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String login(UserReq userReq) {
|
||||
return ComponentFactory.getUserAdaptor().login(userReq);
|
||||
public String login(UserReq userReq, HttpServletRequest request) {
|
||||
return ComponentFactory.getUserAdaptor().login(userReq, request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public class UserTokenUtils {
|
||||
this.authenticationConfig = authenticationConfig;
|
||||
}
|
||||
|
||||
public String generateToken(UserWithPassword user) {
|
||||
public String generateToken(UserWithPassword user, HttpServletRequest request) {
|
||||
Map<String, Object> claims = new HashMap<>(5);
|
||||
claims.put(TOKEN_USER_ID, user.getId());
|
||||
claims.put(TOKEN_USER_NAME, StringUtils.isEmpty(user.getName()) ? "" : user.getName());
|
||||
@@ -44,22 +44,23 @@ public class UserTokenUtils {
|
||||
claims.put(TOKEN_USER_DISPLAY_NAME, user.getDisplayName());
|
||||
claims.put(TOKEN_CREATE_TIME, System.currentTimeMillis());
|
||||
claims.put(TOKEN_IS_ADMIN, user.getIsAdmin());
|
||||
return generate(claims);
|
||||
String appKey = getAppKey(request);
|
||||
return generate(claims, appKey);
|
||||
}
|
||||
|
||||
public String generateAdminToken() {
|
||||
public String generateAdminToken(HttpServletRequest request) {
|
||||
UserWithPassword admin = new UserWithPassword("admin");
|
||||
admin.setId(1L);
|
||||
admin.setName("admin");
|
||||
admin.setPassword("admin");
|
||||
admin.setDisplayName("admin");
|
||||
admin.setIsAdmin(1);
|
||||
return generateToken(admin);
|
||||
return generateToken(admin, request);
|
||||
}
|
||||
|
||||
public User getUser(HttpServletRequest request) {
|
||||
String token = request.getHeader(authenticationConfig.getTokenHttpHeaderKey());
|
||||
final Claims claims = getClaims(token);
|
||||
final Claims claims = getClaims(token, request);
|
||||
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
|
||||
String userName = String.valueOf(claims.get(TOKEN_USER_NAME));
|
||||
String email = String.valueOf(claims.get(TOKEN_USER_EMAIL));
|
||||
@@ -76,7 +77,7 @@ public class UserTokenUtils {
|
||||
log.warn("{}, uri: {}", message, request.getServletPath());
|
||||
throw new AccessException(message);
|
||||
}
|
||||
final Claims claims = getClaims(token);
|
||||
final Claims claims = getClaims(token, request);
|
||||
Long userId = Long.parseLong(claims.getOrDefault(TOKEN_USER_ID, 0).toString());
|
||||
String userName = String.valueOf(claims.get(TOKEN_USER_NAME));
|
||||
String email = String.valueOf(claims.get(TOKEN_USER_EMAIL));
|
||||
@@ -87,11 +88,13 @@ public class UserTokenUtils {
|
||||
return UserWithPassword.get(userId, userName, displayName, email, password, isAdmin);
|
||||
}
|
||||
|
||||
private Claims getClaims(String token) {
|
||||
private Claims getClaims(String token, HttpServletRequest request) {
|
||||
Claims claims;
|
||||
try {
|
||||
String appKey = getAppKey(request);
|
||||
String tokenSecret = getTokenSecret(appKey);
|
||||
claims = Jwts.parser()
|
||||
.setSigningKey(authenticationConfig.getTokenSecret().getBytes(StandardCharsets.UTF_8))
|
||||
.setSigningKey(tokenSecret.getBytes(StandardCharsets.UTF_8))
|
||||
.parseClaimsJws(token.startsWith(TOKEN_PREFIX)
|
||||
? token.substring(token.indexOf(TOKEN_PREFIX) + TOKEN_PREFIX.length()).trim() :
|
||||
token.trim()).getBody();
|
||||
@@ -101,14 +104,15 @@ public class UserTokenUtils {
|
||||
return claims;
|
||||
}
|
||||
|
||||
private String generate(Map<String, Object> claims) {
|
||||
return toTokenString(claims);
|
||||
private String generate(Map<String, Object> claims, String appKey) {
|
||||
return toTokenString(claims, appKey);
|
||||
}
|
||||
|
||||
private String toTokenString(Map<String, Object> claims) {
|
||||
private String toTokenString(Map<String, Object> claims, String appKey) {
|
||||
Long tokenTimeout = authenticationConfig.getTokenTimeout();
|
||||
long expiration = Long.parseLong(claims.get(TOKEN_CREATE_TIME) + "") + tokenTimeout;
|
||||
Date expirationDate = new Date(expiration);
|
||||
String tokenSecret = getTokenSecret(appKey);
|
||||
|
||||
SignatureAlgorithm.valueOf(TOKEN_ALGORITHM);
|
||||
return Jwts.builder()
|
||||
@@ -116,8 +120,24 @@ public class UserTokenUtils {
|
||||
.setSubject(claims.get(TOKEN_USER_NAME).toString())
|
||||
.setExpiration(expirationDate)
|
||||
.signWith(SignatureAlgorithm.valueOf(TOKEN_ALGORITHM),
|
||||
authenticationConfig.getTokenSecret().getBytes(StandardCharsets.UTF_8))
|
||||
tokenSecret.getBytes(StandardCharsets.UTF_8))
|
||||
.compact();
|
||||
}
|
||||
|
||||
private String getTokenSecret(String appKey) {
|
||||
Map<String, String> appKeyToSecretMap = authenticationConfig.getAppKeyToSecretMap();
|
||||
String secret = appKeyToSecretMap.get(appKey);
|
||||
if (StringUtils.isBlank(secret)) {
|
||||
throw new AccessException("get secret from appKey failed :" + appKey);
|
||||
}
|
||||
return secret;
|
||||
}
|
||||
|
||||
private String getAppKey(HttpServletRequest request) {
|
||||
String appKey = request.getHeader(authenticationConfig.getTokenHttpHeaderAppKey());
|
||||
if (StringUtils.isBlank(appKey)) {
|
||||
appKey = authenticationConfig.getTokenDefaultAppKey();
|
||||
}
|
||||
return appKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ const LoginPage: React.FC = () => {
|
||||
<Input
|
||||
size="large"
|
||||
type="password"
|
||||
placeholder="密码: admin123"
|
||||
placeholder="密码: 123456"
|
||||
onPressEnter={handleLogin}
|
||||
prefix={<LockOutlined />}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user