Use yml configuration instead of standalone.xml - java

I have lots of microservices and they work in a similar format. What my requirement is to make my confiuration.yml files work also for keycloak instead of working with standalone.xml (because of my requirements from our customers). I did not see any option that I can override when I check keycloak’s source code since the configuration is done before SPIs.
What I will go in worst scenario is to run some program to convert given configuration.yml to standalone.xml. I appreciate to hear any ideas about how to achieve this. Basically I want to work with YML instead of XML either natively importing something in keycloak or having some converters.
Maybe you can ask why you need this (even for customers), since all of our microservices works like;
server:
port: 80
we don’t want to force our clients to learn any different logic to edit our microservices. They will do always in same way to change some basic configurations like above and we can convert these values to proper standalone.xml way. So can I achieve this converter natively extending keycloak or what could be the best option?

It depends on what settings you want to extract to yml. Standalone.xml allows you to specify configuration values as properties like
<socket-binding name="http" port="${jboss.http.port:8080}"/>
so you can provide a properties file or prorety value during startup like
./standalone.sh --properties=foo.properties -Dfoo=bar
but in your case you could store all of this properties in yml and use some startup wrapper for keycloak that will parse your yml and expose all its settings as java properties like:
#!/bin/bash
./standalone.sh $(magictool foo.yml)

Related

Spring Web App Deployment:: how do you hide data in application.properties?

everyone!
this is going to be my first time pushing a newly developed Spring Boot App and I was wondering if there is a way to protect passwords and other sensitive information written in the application.properties file.
Assuming we have the following lines:
# PostgreSQL connection settings
spring.datasource.jdbc-url=jdbc:postgresql://localhost:5432/bdreminder
spring.datasource.username=username
spring.datasource.password=password
The source code is to be first stored on GitHub and having the credentials stored in plain text does not seem to be a good idea.
So, I could probably add the file to the .gitignore one; I could set some environment variables on the host but how would it populate the .properties file afterward? Also, this seems quite cumbersome in terms of the scaling later on.
So, basically, I am trying to see how it is done in a real-life :)
Please, help :)
Simplest option is to create a profile specific application.properties file and activate that profile. So for example create application-private.properties and activate profile private. Of course you have to watch out to not commit this file.
Alternatively, and probably a safer option, is to define a file outside your project and import it in your application.properties with following line:
spring.config.import=file:../path/to/your/external.properties
Spring Boot has extensive support for external configuration. The usual approach is to use one of environment variables, configuration provided by a platform such as Kubernetes, or a specialized configuration system through Spring Cloud Config; these all keep secrets (or just environment-specific information) entirely outside of the code. They also have the advantages of providing a common style of configuration for other applications that do not use Spring Boot.

How to avoid hard coded database credentials in code

I've been searching for a way to avoid hard coding my database credentials into my code base (mainly written in Java), but I haven't found many solutions. I read this post where they said a one way hash could be the answer. Is there another way of securely connecting to a database without running into the risk of someone decompiling your code?
Just to clarify, I'm not looking for code, rather a nudge in the right direction.
If you can used spring boot application, then you can configure using cloud config method. I have added some postgresql db connection details for your further reference. Please refer following link for spring boot cloud config. spring_cloud
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://{{db_url}}:5432/{{db_name}}
spring.datasource.username=postgres
spring.datasource.password=
spring.datasource.maxActive=3
spring.datasource.maxIdle=3
spring.datasource.minIdle=2
spring.datasource.initialSize=2
spring.datasource.removeAbandoned=true
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=3
spring.datasource.tomcat.test-on-borrow=true
You could load a config file in your code. Define some kind of file, such as JSON or XML, and define all of your configurations in there. You could point to the file as a command line argument, or just hardcode the file path.
Here's a post talking about parsing JSON config in Java:
How to read json file into java with simple JSON library
You can refer to these post. They are basically just saying to either hash, store it in a property file or use an API. Some of the posts are not merely on Java but you can get ideas from them.
How can I avoid hardcoding the database connection password?
https://security.stackexchange.com/questions/36076/how-to-avoid-scripts-with-hardcoded-password
https://www.codeproject.com/Articles/1087423/Simplest-Way-to-Avoid-Hardcoding-of-the-Confidenti
The solution in our team, database as a service,other application use it's API to get database credentials,the request contains simple credentials like application name.
You have several options to avoid hard code values in your source code:
Properties using Advanced Platforms
Properties from Environment variables
Properties from SCM
Properties from File System
More details here:
https://stackoverflow.com/a/51268633/3957754

Dropwizard config override

I am developing a RESTful service with Dropwizard. Now I need deploy it to different environment(test, staging, prod) & data centers(cn, us, etc). As such, it needs different config for different environment/data-center.
Curious how is this usually handled? I could potentially have one config for each env/dc, but in that case, they will have a lot of duplication of common config.
I was expecting that I have a base config, say base.yaml, containing the common configs; And then each environment&DC will have one config, which extend/override the base yaml with their custom config. Is this possible within Dropwizard?
Thank you!
I don't think DropWizard has that feature, but you can always write a small script that composes a few YAML files and starts DropWizard with the result. You can use a simple template engine like Mustache for it.
config-template.yml:
# ...
server:
applicationConnectors:
- type: http
port: {{PORT}}
config-parms-us.yml:
---
PORT: "8080"
---
And then use:
mustache config-parms-us.yml config-template.yml > config.yml
java ... server config.yml
I think this is what you are looking for:
https://github.com/constretto/constretto-dropwizard
It allows you to have environment specific configuration like this:
database: # the JDBC URL
url: jdbc:oracle:thin:#//oracle-testing:1521/name
.staging.url: jdbc:oracle:thin:#//oracle-staging:1521/name
.production.url: jdbc:oracle:thin:#//oracle-production:1521/name
When you want to start your application with certain environment use:
-DCONSTRETTO_TAGS=$ENVIRONMENT
You can create your own configuration bundle which implements Bundle to add your own configuration settings.
So you also need to create your own ConfigurationSourceProvider, then override the open(String path) method, so here you can do find your configuration basename.
Finally you can implements EnvironmentAware which can help you resolve all your configuration files which is a list of url. And you can set your default name you want to loaded.

Spring use one application.properties for production and another for debug

I have a Spring application and I would like to be able to switch between configurations depending if I'm debugging the server or if the server is running in production. (the difference in configurations being things like database location.)
Ideally, I'd like to pass in a command line argument to my Spring application on boot-up and set the application configuration.
I have two separate application.properties files, one with the production values, and another with the debug values. How can I switch between the two of them?
You can have 3 properties files, application-dev.properties, application-prod.properties and application.properties. And you can specify all the development properties in your dev properties file and production cionfiguration properties in your prod file
and specify the profile in your application.properties files as below
spring.profiles.active=dev
or you can select/override the profile using -Dprofile= argument in command line.
Spring profiles seem the way to go. You can start your application with something like -Dprofile=. Have a look at this example.
EDIT: after re-reading your question, I came to the conclusion that you might actually want something more basic: put your database properties externally. Depending on your application you could use #Value of a property configurator. Have a look at the spring docs.

Spring Best approach for multiple environments

I have the following:
System A - Authorization (REST API)
System B - Needs to check for auth
System C - Needs to check for auth
System D - Needs to check for auth
And I have many environment:
Development
Homolog
Production
Each one will have different URLs for System A. So I want to create a project that will integrate those systems. Since All Systems use Jersey and Spring, I can create one filter (jersey) that will abort the request in case the user is not authorized.
So the idea is to create Integration System that will be a JAR with Jerseys filters and uses the parents configuration (Active profile from Spring) to get the correct URL. I might even use this JAR to make System B communicate with System D also, if I can make this work.
The trick is, making this JAR get the correct .properties file based on the Enviroment (set on the parent-project). To be honest, I dont know where to begin.
Reading the DOCs for Spring Environment I found:
Do not use profiles if a simpler approach can get the job done. If the only thing changing between profiles is the value of properties, Spring's existing PropertyPlaceholderConfigurer / may be all you need.
I could have 3 different properties files (development, homolog or production) or I could have one properties file with different keys:
system.a.url.develpment=http://localhost:8080/systemA/authorize
system.a.url.homolog=http://localhost:8081/systemA/authorize
system.a.url.production=http://api.systemA.com/authorize
What is the best approach? What would you do?
In such "simple" case I would only use property file for configuration of urls and have different config files for different environments (dev, prod,..) with one (same named property), e.g.
system.a.url=http://localhost:8081/systemA/authorize
You can manage your property files manually (e.g. outside your jar/war) or you can use maven profiles to make jar/war file specific for your environment. But I don't see the need for spring profiles.
EDIT: Alternatively you can use environment variables to "configure" settings specific to an environment (what a coincidence in the names :)). Note that you can have different environments also inside one machine. For more details check e.g. this.
export AUTH_URL="http://localhost:8081/systemA/authorize"

Categories