What is the simplest way to add application users in a Thorntail WildFly server? - thorntail

As said in the title, is there a way to add application users in Thorntail WilFly server, much like you would do with "add-user.sh -a" script in the full server distribution?
I understand you can provide an external configuration file to Thorntail but that seems a bit of overhead just for specifying where users are located.
Thanks

The answer by Thomas Herzog is very good from a conceptual point of view -- I'd especially agree with securing the application using an external Keycloak, potentially with the help of MicroProfile JWT. I'm just gonna provide a few points in case you decide not to.
You can define users directly in project-defaults.yml, like this:
thorntail:
management:
security-realms:
ApplicationRealm:
in-memory-authentication:
users:
bob:
password: tacos!
in-memory-authorization:
users:
bob:
roles:
- admin
The project-defaults.yml file doesn't have to be external to the app, you can build it directly into it. Typically, in your source code, the file will be located in src/main/resources, and after building, it will be embedded inside the -thorntail.jar. It can be external, of course, and if this is something else than a throwaway prototype or test, sensitive data like this should be external.
You can also use the .properties files from WildFly:
thorntail:
management:
security-realms:
ApplicationRealm:
properties-authentication:
path: .../path/to/application-users.properties
properties-authorization:
path: .../path/to/application-roles.properties

It depends on for what you need the users? Thorntail creates standalone Microservices, which are different to hosted applications in a wildfly-server.
Is there are a management console in thorntail?
Yes there is, but I have never used it.
https://docs.thorntail.io/2.2.0.Final/#_management
https://docs.thorntail.io/2.2.0.Final/#_management_console
The users you maybe able to create there shouldn't be persistent, because there is no wildfly-server installation as you are used to with a standalone wildfly-server installation, it is all packaged in the jar. A Microservice shouldn't need to be configured after its deployment anymore, at least not like this.
How to secure my application?
I would recommend to use an external user management via keycloak, which is integrated in thorntail via the keycloak fraction. With the keycloak fraction you can define security constraints to your endpoints similar in a web.xml.
https://docs.thorntail.io/2.2.0.Final/#_keycloak
Another way is to use the security fraction which provides you JAAS support for your microservice.
https://docs.thorntail.io/2.2.0.Final/#_security
The configuration is done via the thorntail specific project-defaults.yml configuration file, where you can configure the fractions via YAML.
What is a thorntail fraction?
A thorntail fraction is similar to a spring boot start dependency with spring, whereby the fraction provides the API for the developement and bundles the implementation and integration into thorntail. The fraction actually is a jboss module which is packaged into the standalone Microservice during re-packaging phase.
Where can I find examples?
See the following links for examples how to use security in thorntail. You should take a look at them.
https://github.com/thorntail/thorntail-examples/tree/master/security
Take a look at the src/main/resources/projects-defaults.yml which contains the configuration for thorntail fractions and the pom.xml which defines the used fractions.

Related

Log4j Vulnerability (CVE-2021-44228) on Google Cloud Platform and PCF

Currently there are so many suggested steps that have been posted for excluding log4j-core library from dependency or upgrading to the latest (above version 2.15) version according to Spring Blog . Are there any recommended tools that can be used for protecting spring application deployed in Google App Engine or Pivotal Cloud Foundry(PCF) for protecting instead of patching them for redeployment?
Another necessary question is, does it make my application(microservice spring application) to be vulnerable if it uses another microservice for some of its service if it depends on another microservice and if that microservice already uses vulnerable version of log4j-core?
In regard to your first question, you can set an environment variable in order to disable the replacement lookups in log4j:
LOG4J_FORMAT_MSG_NO_LOOKUPS=true
Please note that this only works for log4j >= 2.10.
I believe you can set environment variables in PCF without having to redeploy the service (of course, a restart would be needed), so no new release would be needed. See: https://docs.pivotal.io/pivotalcf/2-3/devguide/deploy-apps/environment-variable.html and https://cli.cloudfoundry.org/en-US/v6/set-env.html
In order to see whether your spring-boot application is vulnerable to the exploit, you could use a spring-boot test I created for that purpose: https://github.com/chilit-nl/log4shell-example - You could test your application with and without the environment variable, to see if it has any effect (assuming that your application currently is vulnerable).
Short answer to your first question is may be. You can protect your application/service by using rules in WAF to discard the ${jndi://ldap pattern. However, there are so many mutations of this (base64 encoding etc.) that it will not be foolproof. If you are worried about dependencies, you should set the JVM Parameter and redeploy your app to prevent the lookup as a workaround.
Regarding your 2nd question - the answer is yes if the the 2nd micro service is being passed the same input and it's logging.

Spring Boot: Handle configuration in multitenant application

I am implementing a Spring Boot application which will be providing a multitenant environment. That is achieved in my case by using a database schema for each customer. Example see this project.
Now I am wondering how to implement tenant-specific configurations. I am using #ConfigurationProperties to bundle my property values, but these are getting instantiated once and not for each tenant.
What if I would like to use Spring Cloud Config with multiple tenant specific git repository as an configuration backend. Would it be possible when using a jdbc backend for Spring Cloud Config?
Is there any way with default Spring mechanisms or do I have to implement a database based configuration framework myself?
Edit: For example I have two tenants called Tenant1 and Tenant2. Both are running over the same application in the same context and are writing in the database schemes tenant_1 and tenant_2.
Identification of tenants is happening over keycloak (see Spring Keycloak multi tenant example). So I identify the tenantId from the jwt token and select the database connection like described here.
But now I would need the same mechanism for #Configuration beans. Since #Configuration beans are as far as I know Singletons, so there is always ONE configuration per application scope, and not ONE configuration per tenant.
So using Spring Cloud Config Tenant1 is using https://git-url/tenant1, Tenant2 is using Hashicorp Vault as backend and perhaps Tenant3 will be using a jdbc based configuration backend. And all of that in ONE (of course scalable) application.
In case your application uses tenant specific files (html templates etc), the following can be applied. As I have used the below approach for handling many tenants and works fine and easy to maintain.
I would suggest that you maintain a consistent configuration source (JDBC) for all of your tenant configurations. This helps you have a single source that is cacheable and scalable for your application. Also, you could have your tenants navigate to a configuration page to manage their settings and alter them to suit their needs at any point of time on the fly. (Example Settings: Records Per Page, Theme, Logo, Filters etc...)
Having the tenant configuration in files in git will be a difficult task when you wanted to auto-provision tenant's when they sign-up as it will involve couple of distributed services. Having them in a TenantSettings table with the tenantId as a column could help you get the data in no time and will be easy.
You can use Spring Cloud Config for your scenario and it is adoptable. It is easily configurable and provides out of the box features. For your specific scenario, you can have any number of microservices running yet all controlled by one Spring Cloud Config Server which is connected to one Git Repository. Your all microservices are asking configuration properties from Spring Cloud Config Server and it is directly fetching properties from Git Repository. That repository can have multiple property files. It can hold common properties for all the microservices or specific service based configuration properties. If you want to keep confidential properties more securely, that is also made possible via HashiCorp vault. I will leave an image below for you to get a better idea about this concept.
In the below image, you can see the Git Repository with common configuration property files and specific configuration property files for different services yet in same repository.
I will add another image for you to get a better idea how does this can be arranged with application profiles as well.
Finally I will add something additional to show the power of Spring Cloud Config and out of the box features it allows us to play with. You can automatically refresh configuration properties in running application as well. You can configure Spring Cloud Config to do that. I will add an architectural diagram to achieve that.
References for this answer is taken from Spring in Action, Fifth Edition
Craig Walls

Spring Boot best practices for hiding or encrypting passwords

I have been using the Spring Framework for about 4 years now, and now Spring Boot for the last couple of months. My Spring MVC applications are usually deployed on a Java EE container such as JBoss/WildFly or WebLogic. Doing so allows me to use JNDI for things like datasources or any other sensitive data that involve secrets/passwords. That makes my app "consume" that JNDI resource based on its name.
Now with Spring Boot and especially for self-contained microservices (embedded tomcat), that information is now stored within the application (application.properties and/or in Spring Java Config classes), so versioned in Git.
That makes that information a lot more exposed to other developers, which I'm not very comfortable with. I also don't like having those details show up in SonarQube and Jenkins (through workspaces).
Question is: Are there any best practices for this specific requirement?
* UPDATE *
I see some articles here and there about the use of Jasypt, but I wonder if it's still a valid library to use since the last stable release is dated from 2014.
Thank you
You could consider using a vault. Spring supports a few of them out of the box. You can find more information here http://projects.spring.io/spring-vault/.
If you have spring cloud in your stack, then it's very easy. Use encrypt the value and put it in the application properties. Follow the instruction mentioned here.
Other way is, set the values as environmental variables and using the environmental variables in the application properties. Instructions here

Including profiles via a Spring Boot starter

I'm having issues with a custom Spring Boot starter. How can a starter cause a profile to be included and pull related configuration from a config server?
Perhaps my use case is unique, because I haven't found any helpful information online. I'm working in an enterprise environment and this starter is for use by my team, so we're able to control some things (like profile names) that perhaps wouldn't make sense in the open source world.
Here is the scenario: We have a Spring Cloud Config Server running to provide configuration. Across our Spring Boot projects, we have standardized on certain profile names such as "prod" and "nonprod" to control configuration in our different environments. I am trying to create a starter to provide reusable functionality. For example purposes, let's say I'm creating a starter that provides an interface to an appliance that performs cryptographic work for us. This starter will need the IP address of the appliance and various other configuration which differs between production and non-production.
Within the config repo, I will have files such as application.yml, application-nonprod.yml, application-nonprodEncryption.yml, etc.
My goal is to have the custom encryption starter automatically include the nonprodEncryption profile when that starter is included in an application. By doing this, apps which don't need encryption do not load the encryption related properties.
Here are my experimental findings so far:
Within an application's bootstrap.yml, I can put a block such as
spring.profiles: nonprod
spring:
profiles:
include:
- nonprodEncryption
and that produces the desired result (i.e. the application-nonprodEncryption.yml file is loaded from the config server and used), but this is an undesirable solution as every app that uses my custom starter would need to include this boilerplate configuration.
When I move the above configuration to the starter's bootstrap.yml, it seems to have no effect.
When I move the above configuration to the starter's application.yml, it seems to be applied (i.e. it shows up in the The following profiles are active: list), but it is too late in the lifecycle to cause the appropriate configuration to be pulled from the config server.
Other things I've considered:
Why not just put all of the configuration into the main profile config file (e.g. application-nonprod.yml)? From a separation of concerns and maintenance standpoint, I'd like to keep configuration for individual starters isolated from each other. Also, some configuration data is more sensitive than other config data, so I don't like the idea of exposing all of the configuration to all apps, since many apps won't need some of the more sensitive configuration. Yes, they could get to it, but why load it into their memory if they don't need it?
Why not just specify the extra profiles when we launch the app? These apps will be running on a cloud platform. The platform will specify either "prod" or "nonprod" as the profile based on which tier the app is running in. I want to manage that at the platform level rather than the app level, so I want the list of profiles provided at app launch to be uniform across all apps (add adding, for example, nonprodEncryption to the list just gets me into the same situation as above - all apps would have all of the configuration, so I might as well just put it all in a single file).
We are currently using Spring Boot 1.5.10.
Any thoughts on how to achieve what I'm trying to do?
I finally found a solution (in case anyone else finds themselves in the same spot).
Step 1: Add a configuration class like this to your starter:
package com.company.bootstrap;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Profile;
#Configuration
#Profile("nonprod")
public class BootstrapNonprod {
public BootstrapNonprod(ConfigurableApplicationContext ctx) {
ctx.getEnvironment().addActiveProfile("nonprodEncryption");
}
}
This will conditionally add a profile. In this example, whenever the "nonprod" profile is active, this class will add the "nonprodEncryption" profile.
Step 2: In your starter's spring.factories file, add a line such as this:
org.springframework.cloud.bootstrap.BootstrapConfiguration=com.company.bootstrap.BootstrapNonprod
It seems like it is just that simple.

How to run multiple Spring Boot application sharing same context?

I want to run multiple micro-services app sharing same context so that I can run my custom security filter for multiple spring boot(micro-services) app.
Example:
User services : https://ip:port/myapp/user
Product services : https://ip:port/myapp/product
Comment services : https://ip:port/myapp/comment
And I should run a common filter(Custom Security Filter) for all micro-services.
As #luboskrnac suggests - for the security you could simply extract your common logic into a separate JAR.
Regarding your shared application context (I assume you are just referring to the shared URL space, rather than sharing any particular state across the apps etc), then yes - you should use something like Zuul - this can act as a singular interface between external and all your microservices (which, under the hood would all be running in their own unique application context namespace/port number - but Zuul can group those together and expose them with nice URLs on a consistent location).
Luckily the whole Netflix microservice stack is well supported by Spring, so its reasonably straight forward to get up and running with Zuul and Eureka (the discovery service).
I have a hello-world setup of the stack written up here (along with the code): http://automateddeveloper.blogspot.co.uk/2015/09/spring-boot-netflix-oss-adventure-into.html
Extract that filter into separate JAR that will be used by each microservice. That JAR will be separate project versioned and deployed into your artifact repository independently.
In fact in microservice environment, you will have much more "common" beans/functionality that should be shared across services. Therefore such common JAR is necessary in microservice environment.

Resources