mirror of
https://github.com/PowerJob/PowerJob.git
synced 2025-07-17 00:00:04 +08:00
feat: [auth] improve jwt security
This commit is contained in:
parent
a1edf3dbd5
commit
f174cd9de8
@ -10,7 +10,7 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public interface JwtService {
|
public interface JwtService {
|
||||||
|
|
||||||
String build(Map<String, Object> body);
|
String build(Map<String, Object> body, String extraSk);
|
||||||
|
|
||||||
Map<String, Object> parse(String jwt);
|
Map<String, Object> parse(String jwt, String extraSk);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import com.google.common.collect.Maps;
|
|||||||
import io.jsonwebtoken.*;
|
import io.jsonwebtoken.*;
|
||||||
import io.jsonwebtoken.io.Decoders;
|
import io.jsonwebtoken.io.Decoders;
|
||||||
import io.jsonwebtoken.security.Keys;
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import tech.powerjob.server.auth.jwt.JwtService;
|
import tech.powerjob.server.auth.jwt.JwtService;
|
||||||
@ -44,9 +45,9 @@ public class JwtServiceImpl implements JwtService {
|
|||||||
;
|
;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String build(Map<String, Object> body) {
|
public String build(Map<String, Object> body, String extraSk) {
|
||||||
|
|
||||||
final String secret = secretProvider.fetchSecretKey();
|
final String secret = fetchSk(extraSk);
|
||||||
return innerBuild(secret, jwtExpireTime, body);
|
return innerBuild(secret, jwtExpireTime, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,8 +63,15 @@ public class JwtServiceImpl implements JwtService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> parse(String jwt) {
|
public Map<String, Object> parse(String jwt, String extraSk) {
|
||||||
return innerParse(secretProvider.fetchSecretKey(), jwt);
|
return innerParse(fetchSk(extraSk), jwt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fetchSk(String extraSk) {
|
||||||
|
if (StringUtils.isEmpty(extraSk)) {
|
||||||
|
return secretProvider.fetchSecretKey();
|
||||||
|
}
|
||||||
|
return secretProvider.fetchSecretKey().concat(extraSk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, Object> innerParse(String secret, String jwtStr) {
|
static Map<String, Object> innerParse(String secret, String jwtStr) {
|
||||||
|
@ -42,7 +42,7 @@ public class PowerJobAuthServiceImpl implements PowerJobAuthService {
|
|||||||
|
|
||||||
private static final String JWT_NAME = "power_jwt";
|
private static final String JWT_NAME = "power_jwt";
|
||||||
|
|
||||||
private static final String KEY_USERID = "userId";
|
private static final String KEY_USERNAME = "userName";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public PowerJobAuthServiceImpl(List<BizLoginService> loginServices, JwtService jwtService, UserInfoRepository userInfoRepository, UserRoleRepository userRoleRepository) {
|
public PowerJobAuthServiceImpl(List<BizLoginService> loginServices, JwtService jwtService, UserInfoRepository userInfoRepository, UserRoleRepository userRoleRepository) {
|
||||||
@ -100,8 +100,8 @@ public class PowerJobAuthServiceImpl implements PowerJobAuthService {
|
|||||||
@Override
|
@Override
|
||||||
public Optional<PowerJobUser> ifLogin(HttpServletRequest httpServletRequest) {
|
public Optional<PowerJobUser> ifLogin(HttpServletRequest httpServletRequest) {
|
||||||
|
|
||||||
final Optional<Long> userIdOpt = parseUserId(httpServletRequest);
|
final Optional<String> userNameOpt = parseUserName(httpServletRequest);
|
||||||
return userIdOpt.flatMap(aLong -> userInfoRepository.findById(aLong).map(userInfoDO -> {
|
return userNameOpt.flatMap(uname -> userInfoRepository.findByUsername(uname).map(userInfoDO -> {
|
||||||
PowerJobUser powerJobUser = new PowerJobUser();
|
PowerJobUser powerJobUser = new PowerJobUser();
|
||||||
BeanUtils.copyProperties(userInfoDO, powerJobUser);
|
BeanUtils.copyProperties(userInfoDO, powerJobUser);
|
||||||
return powerJobUser;
|
return powerJobUser;
|
||||||
@ -144,7 +144,7 @@ public class PowerJobAuthServiceImpl implements PowerJobAuthService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Long> parseUserId(HttpServletRequest httpServletRequest) {
|
private Optional<String> parseUserName(HttpServletRequest httpServletRequest) {
|
||||||
// header、cookie 都能获取
|
// header、cookie 都能获取
|
||||||
String jwtStr = httpServletRequest.getHeader(JWT_NAME);
|
String jwtStr = httpServletRequest.getHeader(JWT_NAME);
|
||||||
if (StringUtils.isEmpty(jwtStr)) {
|
if (StringUtils.isEmpty(jwtStr)) {
|
||||||
@ -157,14 +157,14 @@ public class PowerJobAuthServiceImpl implements PowerJobAuthService {
|
|||||||
if (StringUtils.isEmpty(jwtStr)) {
|
if (StringUtils.isEmpty(jwtStr)) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
final Map<String, Object> jwtBodyMap = jwtService.parse(jwtStr);
|
final Map<String, Object> jwtBodyMap = jwtService.parse(jwtStr, null);
|
||||||
final Object userId = jwtBodyMap.get(KEY_USERID);
|
final Object userName = jwtBodyMap.get(KEY_USERNAME);
|
||||||
|
|
||||||
if (userId == null) {
|
if (userName == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.of(Long.parseLong(String.valueOf(userId)));
|
return Optional.of(String.valueOf(userName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BizLoginService fetchBizLoginService(LoginContext loginContext) {
|
private BizLoginService fetchBizLoginService(LoginContext loginContext) {
|
||||||
@ -179,8 +179,9 @@ public class PowerJobAuthServiceImpl implements PowerJobAuthService {
|
|||||||
private void fillJwt(PowerJobUser powerJobUser) {
|
private void fillJwt(PowerJobUser powerJobUser) {
|
||||||
Map<String, Object> jwtMap = Maps.newHashMap();
|
Map<String, Object> jwtMap = Maps.newHashMap();
|
||||||
|
|
||||||
jwtMap.put(KEY_USERID, powerJobUser.getId());
|
// 不能下发 userId,容易被轮询爆破
|
||||||
|
jwtMap.put(KEY_USERNAME, powerJobUser.getUsername());
|
||||||
|
|
||||||
powerJobUser.setJwtToken(jwtService.build(jwtMap));
|
powerJobUser.setJwtToken(jwtService.build(jwtMap, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ class JwtServiceImplTest {
|
|||||||
Map<String, Object> body = Maps.newHashMap();
|
Map<String, Object> body = Maps.newHashMap();
|
||||||
body.put("userId", 277);
|
body.put("userId", 277);
|
||||||
body.put("name", "tjq");
|
body.put("name", "tjq");
|
||||||
|
body.put("language", "简体中文");
|
||||||
|
|
||||||
final String jwtToken = JwtServiceImpl.innerBuild("tjq", 2, body);
|
final String jwtToken = JwtServiceImpl.innerBuild("tjq", 2, body);
|
||||||
log.info("[JWT] token: {}", jwtToken);
|
log.info("[JWT] token: {}", jwtToken);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user