Saturday, January 30, 2016

PoLA and HttpURLConnection

If you are a developer like me you probably heard of 'PoLA' or the Principle of Least Astonishment. The principle is fairly simple. Never surprise a user. Or in this case even more important, never surprise a developer. Unfortunately I got more then I bargained for last week when one our web service clients was generating rogue requests.

Rogue requests you say? Yes, like in; we have no freaking idea where they're coming from. It's one of those moments where managers start running around in circles, panicking and yelling "we're hacked!!" or "please someone turn off Skynet!!".

Anyway, first a little bit of background. In our project we have automatic activity logging which is triggered by aspects when a process starts. This includes the web service client in question and the processing on the endpoint as both of them are part of our system. So at some point we noticed that before the response was sent by the endpoint, a second call from the same web service client came in. This was unexpected as the client is single threaded and no other clients were in the picture. Review and tests pointed out that it was simplyimpossible©® for our client to simultaneous generate another request while the first one was still in progress.

After a long day of debugging and going through too many logs it turned out that the client was in fact disconnected before processing ended on the endpoint. So there requests weren't simultaneous after all. But why did that took us a day to find out? Did we play starcraft2 again instead of working?

Well no, it all started with the HTTP read timeout on the endpoint's container being unexpectedly set lower than we thought. The logging on the endpoint indicated that a reply was generated but the client was actually disconnected before that event because of the read timeout. This was of course not logged by our aspects on the endpoint side as this is decided on a lower level (the HTTP stack) rather then our endpoint itself.

Ok, true, I hear you say, but what about the web service client log? The web service client should have thrown a "ReadTimeoutException" or something similar and that should have been written to the log, right? Well, true, but it didn't. And now it comes, as it turned out the real surprises is inside HttpURLConnection (more specifically the default Oracle internal handler

Did you know that this default impl of HttpURLConnection has a special "feature" which does HTTP retries in "certain situations"? Yes? No? Well, I for once didn't. So what happened was that the timeout exception was indeed triggered on the web service client but silently catched by HttpURLConnection itself by which it decided to do an internal retry on its own. This means that the read() method called the web service on HttpURLConnection remains blocked, like you are still waiting for the response of the first request. But internally HttpURLConnection is retrying the request more then once and thus generating multiple connections. This explained why it took us so long to discover this as the second call was never logged by our code as it is in fact never triggered by our code but by HttpURLConnection internally.

Here some code illustrating this:
import java.util.concurrent.Executors;


 * Created by koen on 30/01/16.
public class TestMe {

 public static void main(String[] args) throws Exception {
  HttpURLConnection httpURLConnection = (HttpURLConnection) new URL("http://localhost:8080/").openConnection();

  if (!(httpURLConnection instanceof {
   throw new IllegalStateException("Well it should really be "
     + "Check if no library registered it's impl using URL.setURLStreamHandlerFactory()");
  System.out.println("Reading from stream...");

 public static void startHttpd() throws Exception {
  InetSocketAddress addr = new InetSocketAddress(8080);
  HttpServer server = HttpServer.create(addr, 0);

  server.createContext("/", httpExchange -> {
   System.out.println("------> Httpd got request. Request method was:" + httpExchange.getRequestMethod() + " Throwing timeout exception");
   if (true) {
    throw new SocketTimeoutException();
  System.out.println("Open for business.");
If you run this, you'll get:
Open for business.
Reading from stream...
------> Httpd got request. Request method was:POST Throwing timeout exception
------> Httpd got request. Request method was:POST Throwing timeout exception
Exception in thread "main" Unexpected end of file from server
Notice that our httpd got two calls while we only did one? If we re-run this, but this time set the magic property we get:
------> Httpd got request. Request method was:POST Throwing timeout exception
Exception in thread "main" Unexpected end of file from server
Putting all this aside, who the hell builds a retry mechanism that isn't really documented nor configurable? Why am I after 15years of Java development (and a network fetish) not aware of this feature? But more over, why the hell is it doing retries on a freaking HTTP freaking POST? PoLA breach detected!

As you probably guessed by now it's a bug ( Not the retry mechanism of course, that's just crap. The bug is that it also happens for a POST (which is by default not idem potent per HTTP RFC). But don't worry, Bill fixed that bug a long time ago. Bill fixed it by introducing a toggle. Bill learned about backward compatibility. Bill decided it's better to leave the toggle 'on' by default, because that would make it bug-backward-compatible. Bill smiles. He can already see the faces of surprised developers around the globe running into this. Please don't be like Bill?

So after some exciting days of debugging the solution was kinda lame. Merely setting the property to false fixed it. Anyway it surprised me enough to write a blog entry on it, so there you have it.

For the sake of completeness: if you run this code inside a container your results may vary. Depending on libraries used and/or your container, other implementations could have been registered which are then used rather than Oracle's internal one (see URL.setURLStreamHandlerFactory()). So now you might be thinking; why is that guy using the default HttpURLConnection then? Does he also drive to work in a wooden soapbox and cut's his grass with scissors? He could better start a fire and use smoke signals instead! Well, I can't blame you for thinking that, but we never deliberate decided on doings this. Our web service in question is a bit special and uses SAAJ SOAPConnectionFactory which on it's turn uses HttpURLConnection, which reverts to the default impl if no one registered another one.
If you use a more managed WS implementation (like Spring WS, CXF or JAX-WS impls) they will probably use something like Apache HTTP client. And of course if you, yourself would make HTTP connections you would opt for the same. Yes, I'm promoting Apache commons HTTP client, that little critter which changes public API more often then an average female changes shoes. But don't worry, I'll stop ranting now.

Thursday, July 24, 2014

Home Automation (Part I)

Being a developer with background in electronics, I sometimes miss the physical aspect of writing software. I don't mean physical like touching other people or something, no, more like writing code that does something physically. Like operating a lamp or a motor. So, some time ago I saw my chances fit for a new side project: home automation.

While investigating what I would need, I Quickly became convinced that besides programming an installing it myself, the biggest challenge would be to get all bits and pieces together. There are a lot of systems and vendors and it is hard to get some objective information, or just information all together. So I decided to start sharing my experience here. Maybe it might serve to some good for other brave souls crazy enough to try the same thing for their homes.

But first, lets start with a good old rant. Why o why is the world of home  automation so badly organized? Let me come again; why? If you enter this world, set aside all open source principles. Do not hope that you  are going to find centralized/useful documentation on how to do things.

Imagine going back in a time machine, where the Internet is not sometimes referred to as the 'interwebs'. Where the Internet is still delivered over slow landlines owned by evil telco's wanting nothing more then your small fortune. Where marketeers did not yet understand that a platform can be offered almost free of charge and that there are plenty of ways to make money. Imagine a world where not everyone speaks German.

German you say? Yes, get used to words as 'Schnittstelle' (not to be confused with the well known Schnitzel) or 'Zählerfernauslesesystem'. Apparently a lot of these companies are German, and while most documents are indeed also available in English, some are left untranslated so you are stuck with the German version. Fact is that most of these sites need to be browsed in English and a second time in German locale to make sure all information surfaced. Some documents simple don't appear otherwise. But it is what it is, so lets suck it up and proceed.

As with every project it all starts with the requirements. This time being the customer myself, having bad, or no, requirements is not going to be an excuse. But here also lies the danger. Home automation is very subjective. Some people want their eggs to be backed automatically in the morning, others just want a panic button. For me it is a subtle mixture between what is doable, what is actually needed and the budget. The must haves:
  • All light points in the house should be able to be programmed and controlled via software. And with all lights I mean all of them, no exceptions
  • Some power circuits needs to be controllable
  • Lights in hallway, toilet, bathroom, garage, storage space, outside side door, outside house need to be operated with motion and or presence sensors. These sensors also needs to be cat proof. I don't want to turn my house into a blinking Christmas tree if my cats decide to play at night
  • Buttons need RGB LEDs. If the toilet is occupied I want to see a red light on the switch. Depending on the mode a 'sensor controlled light' is in, I want this being reflect by the LED. The brightness of the LEDs needs to be adjusted as well depending on the available light
  • Light sensors with timer functionality. For example; the roof lights need to turn on when it's getting dark, but only after 1900h. If it gets dark during daytime (bad weather or something) the lights should not switch on
  • Scene support: lights in the living-room/kitchen need to be dimmed to preset scenes
  • Blinds for the windows need to be controlled automatically.They need to be controlled together (the default) but  also individually
  • Ventilation. If the unit would be to loud at some point, it must be able to be controlled remotely, preferably by a phone
  • Support for programming over Ethernet
  • API for controlling the entire system via software. For example an app, or a dedicated touch panel
  • The interconnection of the components should be using a bus architecture with free topology
Nice to haves:
  • Heating. This is a bit of a gray zone, but it at least the possibilities needs to be investigated
  • Metrics for gas/electricity/water
For me this is where the barrier between useful and affordable automation ends. Audio for example, sure nice things are possible, but this is better controlled  separately. There is plenty of choice in media system with Spotify integration at far better prices. The thing is that for audio one wants to have freedom of choice and not be bound to a single (expensive) product.

Next the hardware. Easier said then done, so first let's try to identify some categories


A barebone PLC, for example the Simatic S7 from Siemens. They are the SAP of automation. You can build nearly anything with them and they are very robust/stable.
However, the thing is that they are barebone. For example, programming is done with STL, which is very low level, comparable to assembler. On the image below you can get an idea  how this looks.

Agreed, you can also opt for a graphical way of programming, like LAD (ladder) but it remains pretty low level. But that's not all. These things have a high cost, which is understandable if you see in which kind of factories they are being used.
There are also other manufacturers which are S7 compliant, such as VIPA, but the price still remains high.

But the biggest downside is probably that there are no ready build HOME components. If you want a push button with LEDs, no problem, but then you have to build it yourself. I like a challenge but this would be a bit too much for me.

Mini PLCs

Siemens Logo! is such an example

While they are cheaper, they still suffer the same drawbacks as its bigger brothers. There are also no real home components and having something simple as LED feedback on a button (e.g. a 'occupied' LED) means you'll have to run an extra wire and an need an additional output just to steer this one LED.

While there is profibus (really expensive, but ok) for Simatic, Logo! has no bus system. This means that if you want 16 switches you'll at least need 17 wires running in your 'data' cable. Double that amount if you want to use LEDs

Don't get me wrong; Logo! (or PLCs) do have a place in home automation. First there is the ease of installation. You don't need cross switches or wiring switches directly to switching points as with a traditional installation. It will be well suited for basic stuff like push buttons (instead traditional toggle switches), programming panic buttons, simple motion detectors etc They are also more favorable over contactors/relays as they dynamically programmed and prices will be almost the same.

Home automation PLCs

Then there are what I call 'home automation PLCs, one of them is the Loxone Miniserver

It is a CPU just like Logo! or Simatic, but more focused on home automation out of the box. It comes shipped with a webserver and phone app allowing instant remote access from your browser/phone. There are also several already build components which you can use straight away. And most of all, it comes with KNX/EIB support (more on that later).

But to use it as the main home automation solution it would suffer the same disadvantages as the previous ones; limited intelligent components(°) and no bus system.

(°) limited, but there are at least extensions like a an IP cam based intercom, RGBW controllers, wireless extension and more (check it out) these home components are not available with traditional PLCs

Real home automation

With "real" I don't mean that these system would be more stable or mature, not at all. But they are more home oriented and therefore a closer match as to what one would need for home automation.

To make it easy I divided them in the closed systems; such as Niko (Belgian company) home control (NHC)  or BTicino (Italian) etc. These are examples of a closed standard and only the manufacturer in question produces components for it.

Then there are the open systems such as KNX/EIB. The latter is an open standard and every one is free to build components compatible with this standard. This means that you don't have a vendor lock-in; you can mix different brands and components, as long as they are KNX/EIB compatible. For example, one can have a MDT pushbutton combined with a Jung dim actuator and a Basalte thermostat. Just as NHC, KNX uses a bus (EIB) with a free topology.

Ok, then what is the best solution? There is no objective answer in which is better. It basically depends on budget, taste and mindset. For example; vendor lock-in is mostly not a good idea. But if you chose a good vendor that "has it all" it can also have advantages. If you go to your local Niko dealer, someone can probably explain all components. You get everything (information, ordering, support) from a single place. No need to endlessly browse the Internet comparing manufacturers or products. On the other hand a closed standard might impose future risks: what if Niko decides to stop producing NHC? They already did that with it's predecessor: Niko bus. Agreed, they solved it with NHC/NB bridge which allows to add NHC components to an existing NB installation. But not all functionality is usable this way.  So if you bought Niko bus some years ago you are already limited in adding new components.

KNX excels in the fact that it has no central processor (unlike PLCs). It is message driven and each sensor/actor has it's own processor. They communicate with each other using telegrams (~messages). A sensor or an actor generates can subscribe to a so called 'group address' (like a multicast address) and it will then be able to pick up telegrams sent to that address by other sensors or actors. Based on the configuration they can decide to do something with the telegram or ignore it. But there lies also it's weak point: each component is responsible for generating or processing telegrams, but it is limited to the logic offered by that component. For example; a light point needs to be switch on conditionally based on the value of a light sensor and the wall-clock time. This clearly involves clock logic. While perfectly possible with KNX, you'll need a separate actor which is able to generate telegrams based on clock schedules. This starts to become a pricing issue as each KNX actor is a processor on its own making them not cheap.

But there is also a solution. The so called KNX/EIB 'servers'. They allow more advanced and centralized programming and form an extension to the traditional KNX sensors and actuators. An example of this is Gira's home server. However, it's price tag is really, really high at €2.200. Luckily, this is where Loxone comes in. Loxone offers the same functionality but at a reasonable price. It can even do more as it is a traditional CPU with KNX/EIB integration. To program your KNX components via Ethernet, you also need an IP gateway. This is again an extra (special) actor. With Loxone you get all of that combined in a single module. So by adding Loxone we get follow things in return:
  • A 'soft entry' into home automation system. It allows for remote access via an API and apps thanks to it's built in webserver. Since it's KNX/EIB compliant, Loxone can be used as the programmatic interface to EIB, not needing extra KNX components
  • KNX/EIB gateway; using Loxone one can program KNX/EIB components using it as a gateway
  • The inputs on the Loxone are not really usable when using EIB. However, the outputs are. By using them you are also saving a 8 digital output KNX actor
  • Actual programming with logic circuits, controllers, smart components, you can even program in pico C  if that would be required

A KNX gateway and 8DO KNX actor already cost more then the entire Loxone setup. So it's a win-win deal: less money for more functionality.

So in the end I decided that an open system (such as KNX/EIB) in combination with a home automation PLC (Loxone Miniserver) combines the best of two worlds. KNX/EIB offers an open standard and freedom of choice in vendors and components. It also decentralized, message driven and open ended architecture which I felt comfortable with. Loxone adds the central processing power and interface to other platforms (web/mobile). It also allows to program all logic you would even need for your home automation at a reasonable price.

There is however one thing to keep in mind. While Loxone Miniserver is KNX/EIB compliant, it cannot be programmed like other KNX components. In other words, Loxone is programmed separately with different software and different 'programming techniques'. But this actually makes sense.  The way a KNX/EIB is programmed does not lend itself for complex logic. After all, KNX/EIB programming is more 'configuring'.
The Loxone development environment is better suited for this, taking full advantage of its possibilities. Do note that a Gira Home server for example is also programmed in a different way than traditional KNX/EIB components, so this is just natural.

In the next part I'll show the components I'm planning to use to meet the requirements and the test board together with the initial programming I did to be able to test everything from my desk.

Tuesday, January 28, 2014

Some Of My Mostly Used Development Mantras (1/2)

Statement: I assume it works this way!
Mantra: assumption is the mother of all fuckups

Let's start with this short fragment from Under Siege2:

In this case his assumption had a rather lethal outcome which you might probably remember if you have seen the movie. But ok, being a mercenary, his situation might seem different from a day to day developer. So going further with this example, you might remember there was also a computer whiz on the train doing stuff like operating the satellite. Now imagine you're that guy and your asked to startup satellite communications. You quickly write some code and in doing so you write this line: 
i = i++;
Normally we would write something as 'i++' leaving out the assignment. However, the assignment seems redundant at most. We assume that it does not has any other side effect and we startup our program. But then suddenly....BOOM! Communication fail, Casey Rayback gets his ass kicked (actually I would love to have seen this), nukes are launched and world peace is far away. Our assumption had a rather negative impact.

Ok, let's see what this is about and make a small test. What do you expect it prints out, do you have any idea why it does so?
int i = 0;
i = i++;
System.out.println("i:"+ i);
While you're thinking about this, let me explain what happens. As can be seen we have an expression, existing of a unary operator and an assignment. As discussed before the assignment is redundant. But besides being redundant it is also causing an unpleasant side effect. It makes this code behave differently then one would expect. If we drop the assignment (just leaving 'i++;') the code would exactly do what you think it would do.

What happens is that when using an assignment, the JVM will put the value of the operands on the so called operand stack before doing something with them. When the expression is evaluated, the value for making the assignment to the left hand variable is popped from the operand stack. That sneaky unary operator follows different rules. It uses the 'iinc' instruction. The iinc instruction takes as parameter a position in the local variable array of the current frame to put it's value.

So, what happens is that "0" is pushed on the local operand stack. Next the variable "i" is incremented by 1 because of the iinc instruction. At this time the local variable 'i' would actually have the value '1'. We can't show this in a normal way, since the assignment/expression is evaluated in a single step. When the assignment is made, it will pop the latest value from the operand stack assigning it to the variable 'i'. This means that 'i' will be overwritten with the value from the operand stack, changing it's value from 1 back to 0.

Note: when you write  'i = ++i;' thinks will work as expected and the assignment is just redundant without side effects. In that case the iinc instruction is executed before pushing the local variable value to the operand stack. The rational is actually no different as when incrementing a variable in a method call; someMethod(++i) or someMethod(i++) . However, with an assignment it seems less clear that a pre or post unary makes any difference, because we tend to relate it to i++ or ++i on a single line where it absolutely makes no difference if the ++ is pre or post.

In nearly every line of code (depending on experience and knowledge) we take assumptions. This works out most of the time because some of the assumptions will be correct.  Incorrect assumptions do not necessarily lead to bugs as they might get balanced out by other assumptions. Or, maybe the side effects are never detected because of the boundaries in which our software operates.

A good way to track down incorrect assumptions in code is to write tests. But that alone is not enough. It is also  important to accept this rule. No matter how brilliant you are, there is always (a lot) of internals you don't know or fully understand. One needs to remain skeptical, don't be lazy. Always try lookup things as much as possible. Even in the case when there is only a little bit of doubt: look it up and/or make small test case. It does cost time and energy, but the ROI (being able to write working and high quality code) will be well worth it.

Statement: don't worry, it's only temporary!
Mantra: there is no such thing as temporary code

Agreed, a lot of things in life are temporary. The
 stock of Westvleteren 12 in my fridge is just one example. But in software projects, "temporary" tends to start a life on its own inflicting poorly designed or written code along its way.

This makes sense if you think about it; I don't think anyone works with the same amount of energy or dedication if something is considered temporary. The problem is however that temporary code will become permanent before you even realize it.

An example I can share on this topic is a user management system which we designed for a previous project. The system was going to be a "temporary" user management system because the "permanent" system was delayed for some reason. I won't go into detail, but the name of the software needed to reflect that it was temporary. So it was named TUM (Temporary User Management system). And you guessed it; in the end the system existed for years to come and over time became the one and only UAM. After a while it even became hard to convince new colleagues that the "T" actually stood for "temporary".

I'm going to put this a bit harsh, but "temporary" helps no one and gives developers a wild card to justify bad decisions, laziness or incompetence. In such situations chances are high that the design will not be what could have been and the resulting code will be suffering quality issues. So the rule is simple: always design or write code in the assumption it will stick around for quite a while. It will be beneficial in the long run as nearly all code will, in one form or another.

But make no mistake friends, no matter how dedicated or how good you are, the dark side is always waiting around the corner. If you are being tempted, simply ask the question how you would feel if your car mechanic decided to fix your brakes "temporary" because he didn't have any idea at the time on how to fix them properly? Enough said I think.

Like most rules, there are exceptions. It would be naive to think that there are no real temporary software projects in general. Of course there are, and fundamentally it is no big issue if that would be the case. The important part is to keep this decision on project management level. Doing so one avoids infecting the team with it.

Don't forget that in the end you're never sure how temporary a project is going to be. And even if the project is really temporary, it's code might still find it's way to other modules or projects in the future.

Saturday, January 4, 2014

Git: Keeping Your History Clean

As we migrated lately from subversion to git, it was clear from the beginning that we needed some extra rules for keeping the history clean. The first thing that we stumbled upon were the so called automatic 'merge commits' performed by git.

In case you don't know what they are; imagine a typical closed project setup with a central repository to share work between multiple developers. Now suppose developer John committed and pushed some changes. In the mean time there is Jim developing something on the same branch on his local repository. Jim has not pulled from central, so the central repository is still one commit ahead. If Jim is ready with his code he commits the changes to his repository. When he now tries to push his work to central, git will now be instructing Jim to pull first (to get the latest changes from central) before he'll be able to push again. From the moment Jim does a "git pull", a merge commit will be made by git indicating the commit done by John.

This is new when coming from subversion as with svn you won't be able to commit in the first place. You would first have to "svn up" before doing "svn commit", so your changes would still be in your local working copy (unlike with git where they are already committed to your local repository). To be clear: these merge commits don't form a technical issue as they are "natural" (to a certain extend) but they do clutter the history a lot.

To show how this would look in our history, we'll simulate this locally using three repositories (central, a bare git repo and john/jim both 2 clones of central). First John commits and pushes john.file1. Then Jim creates and commits jim.file1. If Jim now tries to push his work, he'll be getting:
! [rejected]        master -> master (fetch first)
error: failed to push some refs to '/tmp/central/'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first merge the remote changes (e.g.,
hint: 'git pull') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details
If Jim would simply 'pull' the changes from origin would be merged and Jim will on his turn be able to push his changes to central. All good. However, our history will now contain the so called merge commit as highlighted below:

As said before, this is happening because the local branch has advanced, compared to central, with the commit of Jim. Therefore git can no longer do a fast forward. Git will (by default) basically be merging in the changes it received from origin and thus has to make a commit. Altering the commit message is still possible, but you'll end up with a actual commit either way. The result is that the change appears to be done twice when looking at the history which can be quite annoying. Also, if the team is committing/pushing fast (as they should) a lot of these entries will appear and really start to clutter the history.

A solution for this is to rebase instead of merge. This can be done by doing:
git pull --rebase
When using 'git pull' git will first bring the changes from origin to the local repo and then (by default) merge them into your local working copy. If rebasing instead, git would (temporary) undo your commits, fast forward your branch and the re-apply your changes. These commits will be new commits as the old ones are thrown away. They get a new SHA1 identifier and all the likes.

Rebase is however only a solution in particular scenario's, so we would certainly not make it the defaul for everything. From the Git book :

If you treat rebasing as a way to clean up and work with commits before you push them, and if you only rebase commits that have never been available publicly, then you’ll be fine. If you rebase commits that have already been pushed publicly, and people may have based work on those commits, then you may be in for some frustrating trouble.

As long as you are not playing with commits that have already been pushed out to others there is no problem. We are working in a standard closed Java project with a single central repository that is adhering to these rules:
  • Developers don't synchronize repositories directly with each other, they always go via central
  • Developers don't push to anything else then central
In this case there is no risk for commits to be made public before rebasing them using git pull. Doing so we can safely make 'git pull' rebase automatically for our project master branch using:
git config branch.master.rebase true
Another problem that caught my attention (being triggered when looking into the automatic merge commit problem) is that our branching structure was not optimal. We are using a feature branch approach but as feature branching (and merging) with subversion comes at high pain we only did it if really necessary. However, when using git creating branches and merging is just a breeze so we changed our rules to be more natural:
  • There must be a (in our case; more) stable master branch on which only completed features will be merged into. Theoretically speaking, no one works directly on the master. This implies that almost all work is executed on feature branches
  • Releases are made from a release branch which is a copy of the master branch at the point the release is triggered
  • The master log must be as clean and straightforward as possible: each feature being merged back into the master must be exactly one commit with the log message stating the ticket and the history showing all changes relevant to that feature.
When working like this chances that you get automatic merge commits are very minimal.  Reintegrating features branches would become an (almost) atomic operation avoiding (nearly) any risk for having those automatic merge commits, even when not rebasing. Of course, some rules must be followed before integrating:
  • Code reviews must have been done on the feature, one way or the other
  • The feature branch must first be updated with the latest version of the master. This happened regularly while developing the feature (you want to be as up to date with the master as possible) but certainly a last time before you're planning to reintegrate the feature. With git this means you simply do "git merge master" while on the feature branch and it will complete in matter of seconds. Doing so conflicts (of other features that have been reintegrated in the master in the mean time) can be resolved while on the feature branch.
  • Tests and the likes must be run on the feature and must be 100% success before reintegrating the feature.
When following these rules the following 3 lines will reintegrate the feature succeeding one after the other making it an almost atomic operation and thus practically making rebase unnecessary:
git checkout master
git pull
git merge --no-commit --squash >feature branch<
git commit -am "FEATURE-XYZ"
git push 
Now, even when working like this we leave rebase set to true for the master as it is still possible for the remote to change in the meantime. In the event this happened (after committing the merge) a simple 'git pull' (with implicit rebase) will solve the problem so that our push will succeed.

Other important rules for keeping clean history are making use of '--squash' as used above:

The --squash will drop any relation to the feature it came from. Doing you can create a single commit that contains all changes without taking any other history from your feature into your master. This is mostly what you want. A feature can contain a lot of "junk" commits which you don't want to see on your master. In the typical case you simply want to see the result and not the intermediates. Also note that --squash also implies --no-ff as git will not fast forward even if it's possible (otherwise you would not be able to get a single merge commit in the first place).

To illustrate this, when we would simply be reintegrating using 'git merge' the history would look like this:

Since the feature was updated with the master before reintegrating, git performed a fast forward. If you look at the history the commits from the feature will be in-lined into the master. This gives the impression that all work had been done on the master. We can also see all intermediate commits and other non interesting commits such as the merge commits from updating the feature with the master. Not a real problem, but to see what has been changed you would (possibly) have to go through a lot of clutter and look at each individual commit to get the big picture, which is not what you typically want.

When disabling fast forward (git merge --no-ff) the history would look like this:

A bit better as we can now see which commit are related to feature-xyz. However, the changes are still scattered over different commits and we still have other commits in which we're not interested in. Someone needing history of feature-xyz is normally not interested in how the feature evolved or how many times a class was refactored. Typically you're only interested in the end result: the changes/additions that will be added to the master branch. By adding "--squash" we accomplish a clean and single commit in our master which list all changes for that feature:

Note that the history of the feature is not lost of course. You can still go back the feature branch and look at the history if that would be necesary.

The --no-commit is convenient if you are skeptical (like me) and want to review to changed/added files for a last time before making the reintegration final. If you leave this option out Git will directly commit the merge without leaving you time to do this final check.

On a side note: to perform code reviews on features before they can be reintegrated I tend to create a (local only) branch of the master being a kind of 'dry run' branch. The feature is then reintegrated on that review branch  (without committing changes) just to perform code review. Doing so all changed files will be marked dirty by your IDE making it easy to see what has actually changed (and to compare them with the HEAD revision). Then I gradually commit changes as I reviewed them. When code reviewing is done, the merge will be completely committed on the the review branch and it can then be merged back to the feature branch before it's finally reintegrated into the master branch. I (normally) don't make the review branch remotely visible, and just delete them locally after reviewing is done. Theoretically one can also merge the review branch back to master directly, but since this review branch will be deleted the real feature branch would never got the changes performed by the code review and you would be losing that history.

Friday, November 15, 2013

Oracle Please Stop Shipping Toolbar

Lately I configured a JRE on some windows machine. It was not a developer machine and the goal was to run some Java, so I installed the JRE. Normally I download everything from, but I was lazily this time and google presented as the first result. I never used I know Java is from Oracle, but the paranoia routine in my brain has not yet white-listed this site as having something to do with Oracle and as such I refuse to associate it with them. But hey as I said, I was lazy and the site seemed legit, so I started downloading.

While going through the install wizard, I suddenly got this screen:

I was baffled to see this. The first thing that went through my mind was: f*** ! I must have downloaded a compromised installer! hAx0orz in my interwebs! So I immediately executed evasive maneuvers theta 3 for windows users: No time for checksums! Pulled out the power, ripped out ram and hdd and fried them instantly.

After I was calmed down I was curious in finding out which compromised installer I had downloaded. So I used a working machine to go out on the Internet.  It turned out I was in for an even bigger surprise. It's just part of the official installer!

Even more, this is not even breaking news as it has been around there for quite some time (and I'm not the first one writing about this). It always escaped me since it's only in the JRE, and only in the one you download from *sigh*. The JDK and the JRE exe's comming from don't contain this crap.

This is bad. Really bad. Yeah, ok, you can disable it on install, true, but that won't cut it. The fact that it is only in JRE installs via makes it even worse. People working professionally with Java (requiring a JDK install instead) could see through this if it was in that type of installer (but then it would probably don't generate profit either). However, systems using JRE's are end user systems (or end user systems managed by other professionals). These are the people working with the applications we write. If these people starts to associate Java with crapware then we have a problem.

It might well be that this was a decision taken by SUN and that Oracle now has to live with the contract, but then it's time they end it. This should stop as it's damaging the reputation of Java all together!

I kindly invite you in joining me signing this petition, at least if you also agree this should stop:

Tuesday, October 29, 2013

Building a SOAP Webservices Proxy Module using Spring Webservices

Some time ago I wanted to see how easy it is to write a web services proxy (wsproxy) using Spring Web Services. So, I thought I would share the result on Github. Feel free to use it (Apache v2 license) or let it serve as basis for your own development. The remainder of the article will explain the idea, how I used Spring web services to build it and a short guide on how to use the current implementation.

A wsproxy in this context is a central soap aware access layer which relays messages between systems. This relaying works in two directions; for services hosted internally (inbound mode) but also for services hosted externally were we are the client (outbound mode). One can compare this with a traditional http forward/reverse proxy but instead of operating on application transport it goes one level higher in the stack and deals with application messages; in this case soap.

In outbound mode our internal services will (normally) use the wsproxy as a http forward proxy. It will then deal with delivering the received message to the actual target. For inbound mode the module will act as a reverse proxy accepting incoming messages from external clients and relay them to our internal services.

Before we continue, a few words about forward/reverse proxies:

A forward proxy is something the client explicitly configures in addition to specifying a target URL. The http stack of the client will send the message to the configured proxy and sent the host/port of the actual desired target host via http headers (Host header). The proxy then deals with forwarding the request to the desired target host/port and return the response to the client. Thus the proxy composes the host and port for the target URL out of the http Host header. For the path it will use the path from the request as received from the client. A reverse proxy behaves (from the point of the client) as the actual target server. The client is not aware of any proxies and does neither have to configure anything special. What the client uses as target URL is the URL of the reverse proxy. The reverse proxy will be able to intercept the message from the client and forward it to the actual target within the network. The reverse proxy will required extra configuration as for example the URL (host, port and possibly path) of the target service, as host/port cannot be deduced from the request or http headers.

When using this module, one can still implement an actual http reverse proxy on boundaries for TLS offloading or other transport purposes. For external inbound traffic (messages coming from external clients destined for internal service) the wsproxy module will simply be the second reverse proxy in line for incoming requests. For internal outbound traffic (messages from internal clients destined for external endpoints) the URL of the http reverse proxy will be configured as the target URL for that specific service on the wsproxy module.

One of the features of having such a soap aware wsproxy is centralizing concerns. The goal is that soap traffic passing through can be intercepted. This way we can implement things such as: audit logging, monitoring, access control, message security, ... doing so we create a centralized place to deal with these requirements instead of having to re-implement them per application.

I chose Spring web services because there is no complicated infrastructure or design to understand. It it also very extensible and offers re-use at the right level for our requirements.
However, at this time I should also point out that there are existing solutions out there which can do this as well and more. They often go under the name of xml security gateways and come as software package or fully equipped appliances. As always you should outweigh the benefits of these existing solutions over writing something yourself. Fact is that they don't come for free (to say the least) and you still need someone with the right skills for configuring and maintaining them. As we will see, our requirements are easy to fulfill with a bit of code (and the help of Spring Web Services) giving us all the control we need.

For the requirements I had an easy to extend design in mind with following out of the box requirements:

  • Outbound mode needs to be configuration free for standard usages. This means that when needing to access a new external services our proxy should relay messages without requiring extra configuration
  • Messages passing the gateway need to be logged. Without extra configuration the entire message should be logged by default. Optionally, we need to be able to configure more fine grained which parts needs to be logged for specific services
  • For (mostly external) outbound communication we should be able to configure a forward proxy or override the target with a pre-configured host (an existing reverse proxy or the actual endpoint)
  • The module must be able to forward messages over secure transport in case there is no external reverse proxy present for offloading outbound secure transport. For inbound secure transport we will let this be handled by the container where the module is running on; so this is out of scope for the module
  • Be able to apply and handle message integrity/confidentiality
The component design looks like this:

There are 3 main components. The endpoint (catch-all endpoint in the drawing), which will act as the receiver for the message being sent to the wsproxy. The forwarder, which will relay the message to the target. Finally, the interceptor chains are the hooks where we are able to intercept the messages being sent/received and do something with them.

These 3 components are offered by Spring Web Services; the endpoint is a implementing to be able to receive the raw payload. The forwarder uses and the interceptor chains are and/or depending on which sides they need to function (more on that later). For message security we will use WSS4J, but this is just an implementation of an interceptor, thus not a new component.

It is important to realize that there are two interceptor chains. From the point of the wsproxy, we'll call the first one the "inbound chain". This is the one operating between the client and the wsproxy. The "outbound chain" is the one operating between the wsproxy and target endpoint. So, if we have an internal client accessing an external endpoint via our wsproxy, the inbound chain will be invoked when the message is received by the wsproxy. The outbound chain will be invoked from the moment the wsproxy relays the message to the target endpoint. Spring has two interfaces to distinguish on which "side" the interceptor operates (an interceptor can also implement both interfaces, making it able to function on both sides). The operates on the endpoint side, for the wsproxy this is inbound. The operates on the client side, so for the wsproxy this is outbound. Btw; we're using inbound and outbound rather then the original Spring naming (client/endpoint) to avoid confusion. As you've noticed by now, the wsproxy is also an endpoint and a client. However, when we refer to "client" we mean the actual service client and the "endpoint" is the actual target service.

The module itself will run on a standard JEE servlet container as your typical Spring application. For all inbound traffic the http (or https) connector from the container is used. For all outbound traffic the WebServiceTemplate is used configured with commons httpclient under the hood, which we'll be able to use for both http and https if required. Service identification is done the "doclit" style. This means we take the first element of the body including it's namespace. This is represented as a QName. This identification is important as we'll have configuration on a per service basis, such as the forward proxy, forwarding protocol, endpoint URL mapping, specific loggers etc.

Ok enough of this. let's take this baby for a spin! Import the project in your IDE of choice, make sure you import it as a Maven project as Maven will have to filter the file (this is done automatically via the default profile). Then we will:

  • Setup a normal standalone soap based endpoint
  • Deploy wsproxy
  • Use a web services client to access the endpoint via the proxy module
For bootstrapping a simple endpoint there is a class SimpleEndpoint foreseen in the tests sources which uses the JDK internal JAX-WS and http server to bootstrap a webservice endpoint:
public class SimpleEndpoint {

 public static void main(String args[]) {
  Endpoint.publish("http://localhost:9999/simple", new SimpleWebServiceEndpoint());

 public static class SimpleWebServiceEndpoint {
  public Date getCurrentDate(String randomParameter) {
   return new Date();
Just run this as a new Java application, it will remain running until the process is killed. Boot the wsproxy by deploying the project to your server of choice (I'll be using Tomcat7), there is no extra configuration required. As for the client we'll be using soap-ui (you can also use cURL if you like). In soap-ui we first have to create the project. We do this based on the WSDL exposed by our test service (accessible under http://localhost:9999/simple?WSDL). Next, we'll have to configure our wsproxy module as the http forward proxy in soap-ui:
The soap-ui projects are also availale in the project if you want. Don't forget to enable the proxy settings as explained above, they are not saved as part of the project.

Important: don't forget to disable the proxy settings again if you are starting with a new project. soap-ui will use the proxy settings for standard http traffic and not only for soap/http. For example; when creating a new project based on a WSDL URL, soap-ui will use the http proxy settings as well to retrieve the WSDL. Since the wsproxy module is not a pure http proxy (but a soap proxy instead) it will not allow non-soap traffic through.

The last thing we need to configure is the target URL in soap-ui. The wsproxy module is by default (on tomcat at least) deployed under the context root named after the filename. In our case this means the module is reachable under: http://localhost:8080/ws-proxy/
There are two options:

  • Deploy the module under the root of the application server (/) instead. In that case nothing needs to be changed to the target URL. The target URL will remain the same URL as you would be using without the proxy module
  • Use a context root of choice, but in that case you'll have to prefix the context root to the target URL
In our case we are in the second scenario, this means that we'll have to change the proposed target URL from "http://localhost:9999/simple" to "http://localhost:9999/ws-proxy/simple".

What happens is that soap-ui sends the request to the host/port specified in the proxy settings (it will thus not sent the request to localhost:9999 but to localhost:8080 instead). The path however is retained; the request is actually sent to localhost:8080 with path "ws-proxy/simple". With the module deployed under "ws-proxy" you can now see why this path prefix has to be there. If the path would start with "simple" we would get a 404. The remainder of the path is not important for the infrastructure, as the Spring dispatcher servlet (configuration can be found in WsProxyWebApplicationInitializer) is bound to "/*". So every subsequent path is treated by the servlet in every case.

To be able to forward the message to the actual target, the module will calculate the target URL:

  • First check if there is a pre-configured target URL for the given endpoint based upon the service identification (payload root element + namespace). This is configured in EndpointTargetUrlMapping as we will see later.
  • If nothing found, check if there is a http Host header present, use host:port as the target server. For the path, use the path as present in the request, but subtract the context root under which this module is deployed (if any)
The latter means that in our case the module is deployed under "ws-proxy" and the request path is "ws-proxy/simple", which will result in a target URL of "http://localhost:999/simple" When executing the request, we'll get this answer:

In the wsproxy log file we can see the intercepted request and response being logged:
51948 [http-bio-8080-exec-5] DEBUG be.error.wsproxy.interceptors.internalchain.LoggingInterceptor  - SID:{}getCurrentDate INBOUND SIDE Request:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soapenv:Envelope xmlns:soapenv="" xmlns:wsp="">

51949 [http-bio-8080-exec-5] DEBUG be.error.wsproxy.core.ForwardingClient  - Using information from Host header as hostname/port
51949 [http-bio-8080-exec-5] DEBUG be.error.wsproxy.core.ForwardingClient  - Got webservice forwarding request, sending to:http://localhost:9999/simple
51981 [http-bio-8080-exec-5] DEBUG be.error.wsproxy.core.ForwardingClient  - Using interceptors:[class be.error.wsproxy.interceptors.externalchain.HttpRequestHeaderTransfererInterceptor]
51981 [http-bio-8080-exec-5] DEBUG be.error.wsproxy.core.ForwardingClient$3  - Opening [] to [http://localhost:9999/simple]
51991 [http-bio-8080-exec-5] DEBUG be.error.wsproxy.core.ForwardingClient  - Forwarding (http://localhost:9999/simple) done.
51994 [http-bio-8080-exec-5] DEBUG be.error.wsproxy.interceptors.internalchain.LoggingInterceptor  - SID:{}getCurrentDate INBOUND SIDE Response:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<S:Envelope xmlns:S="">
    <ns2:getCurrentDateResponse xmlns:ns2="">
In the default setup default logging happens on the inbound side. The inbound interceptors are configure here:
public class InboundInterceptors {

 private PayloadRootAnnotationMethodEndpointMapping catchAllEndpointMapping;
 private MessageDispatcher messageDispatcher;

 public static class FirstInlineInterceptors {
  public DelegatingSmartSoapEndpointInterceptor loggingInterceptor() {
   return new DelegatingSmartSoapEndpointInterceptor(new LoggingInterceptor());

 public static class ServiceSpecificInterceptors {


 public static class LastInLineInterceptors {

If you want to configure this logging interceptor also on the outbound side, you can add them in OutboundInterceptors. LoggingInterceptor both implements EndpointInterceptor and ClientInterceptor. To continue with our requirements, there is also an interceptor which is able to log fragments based on XPath expression. The LoggingXPathInterceptor is service specific and hence we'll be adding this one to the ServiceSpecificInterceptors. The difference is that service specific interceptors use PayloadRootSmartSoapEndpointInterceptor which we need to give namespace and payload root element to identify the service. The configured interceptor will only be invoked for that service. The first in line and last in line use DelegatingSmartSoapEndpointInterceptor which will be invoked for any request.
 public static class ServiceSpepcificInterceptors {
  public PayloadRootSmartSoapEndpointInterceptor getCurrentDateLoggingInterecptor() {
   LoggingXPathInterceptor loggingXPathInterceptor = new LoggingXPathInterceptor();
   loggingXPathInterceptor.addRequestXPaths(new WebServiceMessageXPathExpressionMetaData(
     "//*[local-name()='arg0']", "requestParameter"));
   loggingXPathInterceptor.addResponseXPaths(new WebServiceMessageXPathExpressionMetaData(
     "//*[local-name()='return']", "responseParameter"));
   return new PayloadRootSmartSoapEndpointInterceptor(loggingXPathInterceptor, "",
When we execute the request again in soap-ui, we can see that the request argument and response value are extracted logged to our log file:
DEBUG be.error.wsproxy.interceptors.internalchain.LoggingXPathInterceptor - SID:{}getCurrentDate XPATHID:requestParameter VALUE:?
DEBUG be.error.wsproxy.interceptors.internalchain.LoggingXPathInterceptor - SID:{}getCurrentDate XPATHID:responseParameter VALUE:2013-10-28T16:50:29.537+01:00
The WebServiceMessageXPathExpressionMetaData operates by default on the soap body (payload) and treats the given XPaths as mandatory (but non blocking). To see other options check the javadoc on WebServiceMessageXPathExpressionMetaData.

The properties that can be configured are located in the package Following classes exist:

The default Spring profile "local", enabled via Maven the default Maven filter, will resolve them from the properties file in The configuration is always stored as a simple string allowing for easy externalization in for example a JNDI environment. The three first properties determine how messages will be forwarded, to start with EndpointProtocolMapping:

In the above scenario the target URL was automatically deduced from the Host parameters as our internal client was using the module as a forward proxy. Since the host parameters do not contain any notion about protocols, the wsproxy assumed http as the forwarding protocol by default. If don't have a reverse proxy which takes care of offloading TLS, you can ask the proxy module to forward over https instead. You can do this by setting the protocol mapping to https for a specific service:

EndpointTargetUrlMapping allows to define the target URL directly. This is required in the scenario where an external client will be accessing our internal service. In that case the target URL can no longer be deduced; external clients will not use our module as forward proxy but the message will simply end up on our module as it would be the actual service. The module then needs to know to where it should forward the message to:{namespace}payloadRootElementLocalName=http(s)://host:port/path,....
This can also be used to override the target URL all together. The forwarder will first look if there is an explicit URL defined for the given service, if so that one will be given precedence.

The ForwardProxy can be configured when the wsproxy module on its turn needs to communicate via a http forward proxy in order to reach the target. This is also configurable on a per service basis.

Remember that the forward proxy does not change anything on how the target URL is calculated. Instead of directly accessing the target URL, the message will be forward to the configurered proxy if the setting is used:

The keystores point to the keystore configuration containing store location, store password, key alias and key password. They are used when we want to apply message security which we'll cover next.
To satisfy the last requirement (integrity/confidentiality) we'll be using WSS4J via the Spring Wss4jSecurityInterceptor. This interceptor needs to be configured on the outbound side in our example were we have an internal client accessing an external service. The steps we will perform:
  • Setup a secured standalone soap based endpoint
  • Configure the wsproxy with message security for the given service
  • Deploy wsproxy
  • Use a web services client to access the endpoint via the proxy module
For the secured endpoint SimpleSecuredEndpoint is foreseen using JAXWS and WSIT. The WSIT configuration can be found in META-INF/wsit-be.error.wsproxy.SimpleSecuredEndpoint$SimpleWebServiceEndpoint.xml enabling message integrity on our endpoint.
public class SimpleSecuredEndpoint {

 public static void main(String args[]) throws IOException {
  // Set WSIT_HOME manually, we're only using this for testing purposes. This way we can have a dynamic path based
  // on the project location in filesystem to resolve the keystores via the WSIT configuratin in META-INF
  System.setProperty("WSIT_HOME", new ClassPathResource("").getFile().getParent() + "/../config/test-keystores/");
  Endpoint.publish("http://localhost:9999/simple", new SimpleWebServiceEndpoint());

 @WebService(serviceName = "SimpleEndpoint")
 @Addressing(enabled = false, required = false)
 public static class SimpleWebServiceEndpoint {
  public Date getCurrentDateSecured(String randomParameter) {
   return new Date();
Important: the JAXWS implementation shipped with the JDK does not contain WSIT. It is just the JAXWS RI. In order for this to work you'll have to download the latest Metro release yourself which bundles everything together. See Metro home page. When you've downloaded Metro, run SimpleSecuredEndpoint passing along the endorsed system property: -Djava.endorsed.dirs=/path_to_metro/lib. This will ensure the entire JAXWS implementation is used from the external libraries. When everything is running fine you'll be seeing a line: INFO: WSP5018: Loaded WSIT configuration from file: file:/home/koen/.....

The configuration of the WSS4J interceptor enabling message integrity in OutboundInterceptors:

 public Map<QName, List<ClientInterceptor>> customClientInterceptors() throws Exception {
  Map<QName, List<ClientInterceptor>> mapping = new HashMap<>();

  List<ClientInterceptor> list = new ArrayList<>();
  list.add(new LoggingInterceptor());
  mapping.put(new QName("", "getCurrentDateSecured"), list);

  return mapping;

 private Wss4jSecurityInterceptor getCurrentDateServiceSecurityInterceptor() throws Exception {
  Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor();

  // Outgoing
  interceptor.setSecurementActions("Signature Timestamp");
  Pair<String, String> key = keystore.getKeyAliasPasswords().get(0);

  // Incomming
  interceptor.setValidationActions("Timestamp Signature");

  return interceptor;

On line 6 and 7 we add the custom interceptor to the list of interceptors used by the ForwardingClient. We've also added the LoggingInterceptor on the outbound so we can see the secured messages going out and coming in. To test the message security configuration deploy the wsproxy and use soap-ui to fire the request. The soap-ui setup is no different then setup for the non-secured endpoint.

Important:There seems to be an issue with C14N. When the request is sent as normal, WSIT will complain that the calculated digest does not match with the one in the message. I'm going to investigate this further, but this appears to be a problem of WSIT and not WSS4J, since the same problem also happens when soap-ui is configured as a secured client and directly communicates with the endpoint rather then using the wsproxy module. To get around this and see the test working, remove the line feed between the soap Body start element and the payload root start element. Also remove the line feed between the soap Body end element and the payload root end element:

<soapenv:Envelope xmlns:soapenv="" xmlns:wsp="">
The soap-ui projects are also availale in the project if you want. Don't forget to enable the proxy settings as explained before, they are not saved as part of the project.

The result:

<S:Envelope xmlns:S="" xmlns:ds="" xmlns:exc14n="" xmlns:wsse="" xmlns:wsu="" xmlns:xs="">
   <S:Body wsu:Id="_5002">
      <ns2:getCurrentDateSecuredResponse xmlns:ns2="">
Nothing spectacular as the wsproxy added message security when forwarding the request and removed it when returning the response. If we look at the wsproxy log files, we'll first see the request entering on the inboud side:
34   [http-bio-8080-exec-3] DEBUG be.error.wsproxy.interceptors.logging.LoggingInterceptor  - SID:{}getCurrentDate INBOUND SIDE Request:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soapenv:Envelope xmlns:soapenv="" xmlns:wsp="">
The request is secured and forward to the endpoint:
394  [http-bio-8080-exec-3] DEBUG be.error.wsproxy.interceptors.logging.LoggingInterceptor  - SID:{}getCurrentDate OUTBOUND SIDE Request:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soapenv:Envelope xmlns:soapenv="" xmlns:wsp="">
    <wsse:Security xmlns:wsse="" xmlns:wsu="" soapenv:mustUnderstand="1">
      <wsu:Timestamp wsu:Id="TS-518848887F924441AB13830540361321">
      <ds:Signature xmlns:ds="" Id="SIG-518848887F924441AB13830540361916">
The secured response is received from the endpoint;
524  [http-bio-8080-exec-3] DEBUG be.error.wsproxy.interceptors.logging.LoggingInterceptor  - SID:{}getCurrentDate OUTBOUND SIDE Response:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<S:Envelope xmlns:S="" xmlns:ds="" xmlns:exc14n="" xmlns:wsse="" xmlns:wsu="" xmlns:xs="">
    <wsse:Security S:mustUnderstand="1">
      <wsu:Timestamp xmlns:ns15="" xmlns:ns16="" wsu:Id="_3">
      <ds:Signature xmlns:ns15="" xmlns:ns16="" Id="_1">
Security information is processed and validated. If ok, the security information is stripped and the response returned (to our client, soap-ui in this case):
567  [http-bio-8080-exec-3] DEBUG be.error.wsproxy.interceptors.logging.LoggingInterceptor  - SID:{}getCurrentDate INBOUND SIDE Response:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<S:Envelope xmlns:S="" xmlns:ds="" xmlns:exc14n="" xmlns:wsse="" xmlns:wsu="" xmlns:xs="">
  <S:Body wsu:Id="_5002">
    <ns2:getCurrentDateSecuredResponse xmlns:ns2="">
Until now all tests have been done simulating an internal client accessing an external service. In case you want to use the module to do the inverse; serving external clients accessing internally hosted services, it is more of the same. For each internally hosted service to which the module will forward you would have to register a target URL using the configuration parameter. Interceptors continue working the same way, but remember that for example for message security you probably want the Wss4jSecurityInterceptor to be configured on the inbound side, as in this scenario the inbound side is the external facing side. There is no issue in configuring the Wss4jSecurityInterceptor on both inbound and outbound side for different service; all configuration is based on a per service basis.

For example: service x (identified by namespace and payload root element) is an internal hosted service. Service y is an external service which internal clients want to access. For securing our internal service x we would be adding Wss4jSecurityInterceptor as service specific inbound interceptor in the InboundInterceptors configuration. This interceptor will thus only be active on the wsproxy endpoint (only serving the inbound side, in this example the external facing side) and only for service x. For securing the calls to service y, we would register Wss4jSecurityInterceptor in OutboundInterceptors, adding message security for messages being sent to the external service y by the wsproxy module.

Ok, that's about it! Feel free to drop me a message if this was somehow useful or if you have ideas for improvement!

Sunday, September 8, 2013

WS-Security: using BinarySecurityToken for authentication

As we all know, one goal set by WS-Security is to enforce integrity and/or confidentially on SOAP messages. In case of integrity, the signature which is added to the SOAP message is the result of a mathematical process involving the private key of the sender resulting in an encrypted message digest.

Most frameworks, such as WSS4J, will by default only sign the body. If you're adding extra headers, such as a Timestamp header, you'll have indicate explicitly to sign them. Using the Spring support for WSS4J for example, you can set a comma separated list containing the local element name and the corresponding namespace using the securementSignatureParts property.

Below an example how to instruct it to both sign the Body and Timestamp element (and their siblings). This will result in two digital signatures being appended to the message:

Eventually the SOAP message will be send together with the XML digital signature data and in most cases a BinarySecurityToken containing the certificate.

Nothing new so far. However, what struck me is that it seems not widely understood what the goal is of the BST neither how authentication is controlled using it. Let me try to shed some light on this:

The certificate of the sender which is send along with the SOAP message plays the role of identification. You can compare it as being the username++. It should be clear that the certificate inside the message cannot be trusted, neither can a username without verifying the password. So far everyone agrees on that: "yeah of course, certificates need to be validated in order to be trusted and then you're set!"

But that is not the entire story. Validation of the certificate is not the same as authentication. The fact that the certificate in the message is valid and is signed by a known CA is not enough to consider the sender authenticated.

For example: I, in my most malicious hour, could have intercepted the message, changed the content, created a new signature based on my private key and replaced the BST in the message with my certificate. My certificate could perfectly be an official CA signed certificate (even signed by the same CA as you're using) so it would pass the validation check. If the framework would simply validate the certificate inside the message we would have no security at all.

Note: If you're sending the message over secure transport instead, chances are that I was not able to intercept the message. But secure transport is mostly terminated before the actual endpoint, leaving a small piece of the transport "unsecured". Albeit this part will be mostly internally in your company, but what I want to point out is that no matter how secure your transport is, the endpoint has the end responsibility in verifying the identity of the sender. For example; in an asynchronous system the SOAP message could have been placed on a message queue to be processed later. When processing starts by the endpoint, the trace of the secure transport is long gone. You'll have to verify the identity using the information contained in the message.

In order to close this loophole we have two solutions:

The first solution builds further on what we already described: the certificate in the message is verified against the CA root certificates in the truststore. In this scenario it advised to first narrow the set of trusted CA's. You could for example agree with your clients on a limited list of CA's to get your certificates from. Doing so you are already lowered the risk of trusting more "gray zone" CA's which might not take the rules for handing out certificates so strict (like for example, proper checking the identity of their clients). Secondly, because *every* certificate handed out by your trusted CA will be considered "authenticated", we'll close the loophole by issuing some extra checks.

Using WSS4J you can configure a matching pattern based on the subject DN property of the certificate. They have a nice blog entry on this here:
We could specify that the DN of the certificate must match a given value like this:

Wss4jHandler handler = ... 
handler.setOption(WSHandlerConstants.SIG_SUBJECT_CERT_CONSTRAINTS, "CN = ...");
Note: that there is currently no setter for this using the Spring support for WSS4J in Wss4jSecurityInterceptor, so you'll have to extend it in order to enable this!

To conclude the steps being performed:

  1. The certificate contained in the message is validated against the trusted CA in your trustore. When this validation succeeds it tells the application that the certificate is still valid and has actually been handed out by a CA that you consider trusted.
    • This check gives us the guarantee that the certificate really belongs to the party that the certificate claimes to belong to.
  2. Optionally the certificate can also be checked on revocation so that we don't continue trusting certificates that are explictly been revoked.
  3. WSS4J will check if some attributes of the certificate match the required values for the specific service (Subject DN Certificate Constraint support).
    • This would be the authentication step; once the certficate has been found valid, we check if the owner of the certificate is the one we want to give access too
  4. Finally the signature in the message is verified by creating a new digest of the message, compare it with decrypted digest from the message and so forth
It should be noted that this check (at least when using WSS4J) is not done by default! If you don't specify it and simply add your CA's in the trust store you'll be leaving a security hole!

The second solution requires no extra configuration and depends on ONLY the certificate of the sender to be present in the truststore.
The certificate contained in the message is matched against the certificate in the truststore. If they match the sender is authenticated. There is no need to validate certificates against a CA since the certificates imported in the truststore are explicitly trusted (WSS4J will still check if the certificate is not expired and possibly check it for revocation). Again, there are no CA certificates (or CA intermediate certificates) in the truststore! Only the certificates of the senders that you want to give access too. Access is hereby controlled by adding (or removing) their certificate from the truststore.

This requires you to be cautious when initially importing the certificates since you'll have to make sure they actually represent the sender. But this is something you're always obliged to do when adding certificates to your truststore, also when adding CA certificates like in the first solution.

Conclusion: in the assumption you can limit the trusted CA's, the first solution is in most cases the preferred one and also the most scalable. For new clients there are no changes required to the truststore. The attributes to match can be stored externally so they are easy to change/add. Also, when the client certificates expires or gets revoked, you don't need to do anything special. The new certificate will we used by the sender at a given moment and will directly be validated against the CA in your truststore. In the second solution you would have to add the new certificate to the trustore and leave the old one in there for a while until the switch is performed.

Overall lessons learned: water tight security is hard. The #1 rule in IT (assumption is the mother of all f***ups) is certainly true here. Be skeptical and make sure you fully understand what is going on. Never trust default settings until you are sure what they do. The default setting on your house alarm (eg. 123456) is no good idea either. Neither is the default admin password on a Tomcat installation.