Solución:
Puedes usar Jasypt para cifrar propiedades, por lo que podría tener su propiedad así:
db.password=ENC(XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=)
Jasypt le permite cifrar sus propiedades utilizando diferentes algoritmos, una vez que obtenga la propiedad cifrada que puso dentro del ENC(...)
. Por ejemplo, puede cifrar de esta manera a través de Jasypt usando la terminal:
encrypted-pwd$ java -cp ~/.m2/repository/org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="contactspassword" password=supersecretz algorithm=PBEWithMD5AndDES
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 24.45-b08
----ARGUMENTS-------------------
algorithm: PBEWithMD5AndDES
input: contactspassword
password: supersecretz
----OUTPUT----------------------
XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=
Para configurarlo fácilmente con Spring Boot, puede usar su iniciador jasypt-spring-boot-starter con ID de grupo com.github.ulisesbocchio
Tenga en cuenta que deberá iniciar su aplicación utilizando el mismo contraseña que utilizó para cifrar las propiedades. Entonces, puede iniciar su aplicación de esta manera:
mvn -Djasypt.encryptor.password=supersecretz spring-boot:run
O usando la variable de entorno (gracias al enlace relajado de Spring Boot):
export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
mvn spring-boot:run
Puede consultar el siguiente enlace para obtener más detalles:
https://www.ricston.com/blog/encrypting-properties-in-spring-boot-with-jasypt-spring-boot/
Para usar sus propiedades cifradas en su aplicación, utilícela como de costumbre, use cualquier método que desee (Spring Boot conecta la magia, de todos modos, la propiedad debe estar, por supuesto, en la ruta de clase):
Utilizando @Value
anotación
@Value("${db.password}")
private String password;
O usando Environment
@Autowired
private Environment environment;
public void doSomething(Environment env) {
System.out.println(env.getProperty("db.password"));
}
Actualización: para entorno de producción, para evitar exponer la contraseña en la línea de comando, ya que puede consultar los procesos con ps
, comandos anteriores con history
, etc., etc. Podrías:
- Crea una secuencia de comandos como esta:
touch setEnv.sh
- Editar
setEnv.sh
para exportar elJASYPT_ENCRYPTOR_PASSWORD
variable
#! / bin / bash
exportar JASYPT_ENCRYPTOR_PASSWORD = supersecretz
- Ejecute el archivo con
. setEnv.sh
- Ejecute la aplicación en segundo plano con
mvn spring-boot:run &
- Eliminar el archivo
setEnv.sh
- Desmarque la variable de entorno anterior con:
unset JASYPT_ENCRYPTOR_PASSWORD
ACTUALIZAR: Me di cuenta de que la gente rechazaba esto, así que debo decir que, aunque esta no es una solución ideal, funciona y es aceptable en algunos casos de uso. Cloudfoundry utiliza variables de entorno para inyectar credenciales cuando un servicio está vinculado a una aplicación. Más información https://docs.cloudfoundry.org/devguide/services/application-binding.html
Y también si su sistema no se comparte, entonces para el desarrollo local esto también es aceptable. Por supuesto, la forma más segura y protegida se explica en Respuesta de @ J-Alex.
Respuesta:
Si desea ocultar sus contraseñas, la solución más fácil es usar Variables de entorno en application.properties
archivo o directamente en su código.
En application.properties
:
mypassword=${password}
Luego, en su clase de configuración:
@Autowired
private Environment environment;
[...]//Inside a method
System.out.println(environment.getProperty("mypassword"));
En tus configuration
clase:
@Value("${password}")
private String herokuPath;
[...]//Inside a method
System.out.println(herokuPath);
Nota: Es posible que deba reiniciar después de configurar la variable de entorno. Para ventanas:
Consulte esta documentación para obtener más información.
A las soluciones ya propuestas puedo agregar una opción para configurar un externo Secrets Manager
como Vault.
- Configurar Vault Server
vault server -dev
(Solo para DEV y no para PROD) - Escribe secretos
vault write secret/somename key1=value1 key2=value2
- Verificar secretos
vault read secret/somename
Agregue la siguiente dependencia a su proyecto SpringBoot:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
Agregue las propiedades de configuración de Vault:
spring.cloud.vault.host=localhost
spring.cloud.vault.port=8200
spring.cloud.vault.scheme=http
spring.cloud.vault.authentication=token
spring.cloud.vault.token=${VAULT_TOKEN}
Aprobar VAULT_TOKEN
como variable de entorno.
Consulte la documentación aquí.
Existe un proyecto Spring Vault que también se puede utilizar para acceder, almacenar y revocar secretos.
Dependencia:
<dependency>
<groupId>org.springframework.vault</groupId>
<artifactId>spring-vault-core</artifactId>
</dependency>
Configuración de la plantilla de Vault:
@Configuration
class VaultConfiguration extends AbstractVaultConfiguration {
@Override
public VaultEndpoint vaultEndpoint() {
return new VaultEndpoint();
}
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication("…");
}
}
Inyecte y use VaultTemplate:
public class Example {
@Autowired
private VaultOperations operations;
public void writeSecrets(String userId, String password) {
Map<String, String> data = new HashMap<String, String>();
data.put("password", password);
operations.write(userId, data);
}
public Person readSecrets(String userId) {
VaultResponseSupport<Person> response = operations.read(userId, Person.class);
return response.getBody();
}
}
Usar Vault PropertySource
:
@VaultPropertySource(value = "aws/creds/s3",
propertyNamePrefix = "aws."
renewal = Renewal.RENEW)
public class Config {
}
Ejemplo de uso:
public class S3Client {
// inject the actual values
@Value("${aws.access_key}")
private String awsAccessKey;
@Value("${aws.secret_key}")
private String awsSecretKey;
public InputStream getFileFromS3(String filenname) {
// …
}
}