jwt settings workout on review feedback
This commit is contained in:
parent
1f1c8fb013
commit
b95f1c95e0
@ -164,7 +164,11 @@ public class JwtSettingsServiceDefault implements JwtSettingsService {
|
|||||||
if (isAllowedDefaultJwtSigningKey()) {
|
if (isAllowedDefaultJwtSigningKey()) {
|
||||||
log.warn("Default JWT signing key is allowed. This is a security issue. Please, consider to set a strong key in admin settings");
|
log.warn("Default JWT signing key is allowed. This is a security issue. Please, consider to set a strong key in admin settings");
|
||||||
} else {
|
} else {
|
||||||
String message = "Please, set a unique signing key with env variable JWT_TOKEN_SIGNING_KEY. Key is a Base64 encoded phrase. This will require to generate new tokens for all users and API that uses JWT tokens. To allow insecure JWS use TB_ALLOW_DEFAULT_JWT_SIGNING_KEY=true";
|
String message = "UPGRADE ERROR. YOUR ACTION REQUIRED. Please, set a unique signing key with env variable JWT_TOKEN_SIGNING_KEY. " +
|
||||||
|
"The key should be a Base64 encoded string representing at least 256 bits of data. " +
|
||||||
|
"This will require to generate new tokens for all UI users and scripts that use JWT. " +
|
||||||
|
"To keep the default non-secure JWT signing key set TB_ALLOW_DEFAULT_JWT_SIGNING_KEY=true and restart the upgrade. " +
|
||||||
|
"You may change the JWT signing key later in the Admin Settings UI.";
|
||||||
log.error(message);
|
log.error(message);
|
||||||
throw new ValidationException(message);
|
throw new ValidationException(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
package org.thingsboard.server.config.jwt;
|
package org.thingsboard.server.config.jwt;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.bouncycastle.util.Arrays;
|
import org.bouncycastle.util.Arrays;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -23,6 +24,7 @@ import org.thingsboard.server.dao.exception.DataValidationException;
|
|||||||
|
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ -32,11 +34,14 @@ public class JwtSettingsValidator {
|
|||||||
if (StringUtils.isEmpty(jwtSettings.getTokenIssuer())) {
|
if (StringUtils.isEmpty(jwtSettings.getTokenIssuer())) {
|
||||||
throw new DataValidationException("JWT token issuer should be specified!");
|
throw new DataValidationException("JWT token issuer should be specified!");
|
||||||
}
|
}
|
||||||
if (Optional.ofNullable(jwtSettings.getRefreshTokenExpTime()).orElse(0) <= 0) {
|
if (Optional.ofNullable(jwtSettings.getRefreshTokenExpTime()).orElse(0) <= TimeUnit.MINUTES.toSeconds(15)) {
|
||||||
throw new DataValidationException("JWT refresh token expiration time should be specified!");
|
throw new DataValidationException("JWT refresh token expiration time should be at least 15 minutes!");
|
||||||
}
|
}
|
||||||
if (Optional.ofNullable(jwtSettings.getTokenExpirationTime()).orElse(0) <= 0) {
|
if (Optional.ofNullable(jwtSettings.getTokenExpirationTime()).orElse(0) <= TimeUnit.MINUTES.toSeconds(1)) {
|
||||||
throw new DataValidationException("JWT token expiration time should be specified!");
|
throw new DataValidationException("JWT token expiration time should be at least 1 minute!");
|
||||||
|
}
|
||||||
|
if (jwtSettings.getTokenExpirationTime() >= jwtSettings.getRefreshTokenExpTime()) {
|
||||||
|
throw new DataValidationException("JWT token expiration time should greater than JWT refresh token expiration time!");
|
||||||
}
|
}
|
||||||
if (StringUtils.isEmpty(jwtSettings.getTokenSigningKey())) {
|
if (StringUtils.isEmpty(jwtSettings.getTokenSigningKey())) {
|
||||||
throw new DataValidationException("JWT token signing key should be specified!");
|
throw new DataValidationException("JWT token signing key should be specified!");
|
||||||
@ -52,7 +57,11 @@ public class JwtSettingsValidator {
|
|||||||
if (Arrays.isNullOrEmpty(decodedKey)) {
|
if (Arrays.isNullOrEmpty(decodedKey)) {
|
||||||
throw new DataValidationException("JWT token signing key should be non-empty after Base64 decoding!");
|
throw new DataValidationException("JWT token signing key should be non-empty after Base64 decoding!");
|
||||||
}
|
}
|
||||||
Arrays.fill(decodedKey, (byte) 0);
|
if (decodedKey.length * Byte.SIZE < 256) {
|
||||||
|
throw new DataValidationException("JWT token signing key should be a Base64 encoded string representing at least 256 bits of data!");
|
||||||
|
}
|
||||||
|
|
||||||
|
System.arraycopy(decodedKey, 0, RandomUtils.nextBytes(decodedKey.length), 0, decodedKey.length); //secure memory
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,6 +178,7 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
|
|||||||
} else if (EntityType.TENANT.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
|
} else if (EntityType.TENANT.equals(componentLifecycleMsg.getEntityId().getEntityType())) {
|
||||||
if (TenantId.SYS_TENANT_ID.equals(componentLifecycleMsg.getTenantId())) {
|
if (TenantId.SYS_TENANT_ID.equals(componentLifecycleMsg.getTenantId())) {
|
||||||
jwtSettingsService.ifPresent(JwtSettingsService::reloadJwtSettings);
|
jwtSettingsService.ifPresent(JwtSettingsService::reloadJwtSettings);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
tenantProfileCache.evict(componentLifecycleMsg.getTenantId());
|
tenantProfileCache.evict(componentLifecycleMsg.getTenantId());
|
||||||
partitionService.removeTenant(componentLifecycleMsg.getTenantId());
|
partitionService.removeTenant(componentLifecycleMsg.getTenantId());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user