Generating (Maven) Projects

Introduction

The first thing we do when starting a new application is setting up our project. A lot of people use Maven for this, and you have various options how you can do this.
Since I create a lot of projects for testing out various features of the Atbash projects or for trying things out (I have around 300 projects on my computer today) I was searching for some help to do this.

Application setup

When trying things out, I need to have some minimal project setup. Not only do I need the Maven pom file with the required dependencies, I also need some files like configuration or a login file for Octopus.

I do not need to have tools to generate me the JPA entities, JSF Screens or JAX-RS endpoints. Creating a few of them is not difficult with the current IDE’s and that automatic generation is mostly too opinionated so that it is not usable in production systems either.

So what are the options to have this minimal project setup

Copy and Paste

You can always copy such a minimal project you have already created and made some modifications to

  • Change the groupId and artifactId of the pom file
  • Update the dependencies
  • Update the configuration file to match your new dependencies and use case you want to test out.
  • Change the java package with your java code
  • Add or remove code depending on the feature for this use case.

This is a valid procedure and in most cases the most efficient one. You don’t need to learn any new tool, extend it with your features (Like Octopus in my case) but of course, it is not the most fun way of doing things.

JBoss Forge

JBoss Forge https://forge.jboss.org/ is a tool specifically designed to get your application up and running fast. It not only generates the project for you but also can help you in generating those well-structured classes like JPA entities, JAX-RS endpoints, and screens with JSF or Angular(JS).

I used it in the past and it can be a valuable tool but it is not the right thing for what I want.
Although you can generate your maven project, you need a script and/or a custom add-on for the features that I want (specific dependencies within the pom.xml file and some configuration and java files)

It also has a lot of options to generate code for you, but again this is sometimes opinionated and not what you or your company wants to use.

Other tools

Since there are various other tools on the internet, the topic seems to be important for a lot of people. Similar tools which I found are generjee and factorEE.
Not all of them are maintained anymore or do focus on the wrong things (for my use case) like generating code.
I also find a CLI very important in this case since it allows you to create an application very rapidly (and recreate it based on the same configuration)

Jessie

So, due to the lack of the right tool for me, I created one of my own called Jessie (Java EE Start project as it was geared at that time towards Java EE). Last year with the release of CDI 2.0, I did a rewrite of it using the Java SE CDI container and included the usage of ThymeLeaf as templating mechanism so that it became easier to generate files which can be customized.

In the OpenSource spirit of Atbash, I placed the code on Github  and created a front end for it.
You can play with it on the OpenShift V3 instance  or can download the code that just needs a few parameters within a YAML config file and the CLI version generates your project.

The first version has support for Java EE and additional frameworks like DeltaSpike, PrimeFaces, and Octopus, the security framework.

Since I’m also involved with MicroProfile lately, a version for MicroProfile and the support for the different vendor implementation like LibertyIO, WildFly Swarm, Payara Micro etc will be created later on.

Conclusion

When setting up a new project, the most efficient solution is creating it from scratch or start from a similar existing project and make the required adaptations.
Another useful tool is JBoss Forge, mainly when you are interested in generating some code.

Jessie has been created a few years ago as a toy and now available on GitHub and it was a good learning opportunity for CDI 2.0, templating with ThymeLeaf and creating a tool which runs in multiple environments (CLI, Java FX, Web/JSF)

Maybe it is also helpful for you.

Have fun.

Http Signatures for End-To-End protection

Introduction

In a distributed system, it is not enough to know who called you, but you also need to make sure the data which you receive are not altered in transit.
The use of tokens (like Bearer JWT tokens according to the OpenId Connect or MicroProfile JWT Auth specifications) can be captured and briefly used to send fake request to your endpoints.
And SSL (like using HTTPS connections) cannot guarantee that your message isn’t read or altered by someone due to the possibilities of SSL Proxy termination or even Man In The Middle Intermediates who fakes correct SSL.

Encryption or protection

The solution is that your processes somehow make sure that the communication between them is ‘safe’. If the processes themselves (your client and your server application) perform these tasks and not some network layer (SSL, in fact, doesn’t fit in any OSI based network layer) of your (virtual) machine.

When your process is performing these tasks, it is possible to create a security context between the 2 processes and then each process can ensure or detect that the message is unaltered or can’t be read, regardless of any Proxy or Man In The Middle.

Whether you need encryption of the message (because you have confidential data) or signing (sensitive data) depends on the data. But at least you need the signing of the message so that we can guarantee the message is actually sent by someone we trust and isn’t altered.

Http Signatures

There is a standard created to have a mechanism to implement this kind of End To End Protection. It is called ‘HTTP Signatures’ and designed by the IETF. https://tools.ietf.org/id/draft-cavage-http-signatures-09.html

It is very HTTP friendly as it adds an additional header to the request. Within this header, enough information is placed so that the target process can verify if the message was altered or not.

This header is called Signature

Signature : keyId="rsa-key-1",algorithm="rsa-sha256",headers="(request-target) date digest content-length",signature="Base64(RSA-SHA256(signing string))"

The specification defines the structure and framework how the header should be created and the verification process must be performed but leaves a lot of freedom to the developer to tailor this protection to his/her needs.

The idea is that there is a signature calculated based on some parameters which are mostly just other headers. And by calculating them on the receiving side, we can verify if these values are changed.

These parameters are described within the headers parameter, and in the example, the following headers are used (request-target) date digest content-length

The values of these headers are concatenated (there exist a few rules about how to do it) and for this string, the cryptographic hash is calculated the signature.
The calculation is done using the value specified by the algorithm parameter (rsa-sha256 in our example above) and from the key with id rsa-key-1 is used for this in our example.
There are a number of crypto algorithms allowed, but RSA keys are the most popular ones.
This signature value is a binary, so a BASE64 encoded value is placed within the header.

In theory, all headers can be used but some of them are more interesting than other ones.
For example

  • (request-target) is a pseudo header value containing the concatenation of the http method and the path of the URL. If you like to include also the hostname (which can be interesting if you want to make sure that a request for the test environments never hits production, you can add the host header in the set of headers which needs to be used for the calculation of the signature value.
  • date header contains the timestamp when the request is created. This allows is to reject ‘old’ requests.
  • digest is very interesting when there is a payload send to the endpoint (like with put and post). This header contains then the hash value of the payload and is a key point in the end to end protection we are discussing here.

On the receiving side, the headers which are specified within the signature parameter are checked. Like

  • date is verified to be within a skew value from the system time
  • digest is verified to see if the header value is the same as the calculated hash value from the payload.

And of course, the signature is verified. Here we decode the signature value with the public key defined in the keyId parameter, using the algorithm specified.
And that value should match the calculated value from the headers.

Using Http Signatures

I have created a Proof Of Concept how this can be integrated with JAX-RS, client and server side.

For the server side, it is quite simple since you can add filters and interceptors easily by annotating them with @Provider. By just then indicating if this interceptor and filters should need to do their work, verification of the HTTP Signature, you are set to go.

@Path("/order")
@RestSignatureCheck
public class OrderController {

On the client side, you can register the required filters and WriterInterceptor manually with the Client. Something like this

Client client = ClientBuilder.newClient();
client.register(SignatureClientRequestFilter.class);
client.register(SignatureWriterInterceptor.class);

One thing is on the roadmap is to integrate it with the MicroProfile Rest Client way of working so that you can register the Signatures Feature and you’re done.

The initial code can be found on Github.

Conclusion

With the Http Signatures specification, you can add a header which can be used to verify if the message is changed or not. This is a nice non-intrusive way of having an End-To-End protection implement which can complement the SSL features to be sure that no intermediary party changes the message.

Have fun.