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