Friday, September 24, 2010

Secure Web Services - WS-Security

Security is one of the important key in the success of a IT project but most of the time only user authentication or data encryption are taken into account. So security of the application is often not adressed or leave aside due to complexity of the implementation.
One of the reason explaining this situation comes from the fact that solutions or frameworks proposed to secure an application are difficult to configure and maintain. And this remark prevalls over the specification WS-Security.

In large company having deployed WS-Services to allow intra or inter connection between applications, Web application authentication with HTTPS protocol mechanisms are use to secure platforms. That means that users discovering the credentials used to connect to the web server can potentially have access to the services of the company.

WS-Security offers a way to authenticate the user connected to a web service or allow also a user to be trusted on the web server it is connected. This mechanism is interesting because it reinforce the security but provides also a way to restrict access to unauthorized users to web services.

Apache Camel and CXF frameworks offers a simplify way to implement this with only few lines of code and spring beans definition. Let's see that in action :

STEP 1

We only need to use JAAS api to authenticate the user using the following java package "javax.security.auth.callback" and the project WS4J of Apache. Here is a simple example authenticate a user using a list and the password provided.


package org.apache.camel.example.reportincident;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

/**
* Callback handler to handle passwords
*/
public class UTPasswordCallback implements CallbackHandler {

private Map passwords = new HashMap();

public UTPasswordCallback() {
passwords.put("claus", "sualc");
passwords.put("charles", "selrahc");
passwords.put("james", "semaj");
passwords.put("abcd", "dcba");
}

/**
* Here, we attempt to get the password from the private alias/passwords map.
*/
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

String user = "";

for (int i = 0; i < pc =" (WSPasswordCallback)" user =" pc.getIdentifier();" pass =" passwords.get(user);" string="">


STEP 2 This is here that the magic will operates as we will use Spring beans definition with Apache Web Services Framework - CXF and Apache Camel to expose the web service

Instantiate your WS4J bean














Add it as an interceptor to CXF to allow CXF to authenticate the user using the credentials provided in the SOAP header definition.



















Here is an example of the SOAP header






2010-09-24T07:31:06.308Z
2010-09-24T07:36:06.308Z


charles
KoNvkEh9jwgvxTfcTza6+kHkKNI=
havIKNKvlRuatlp3CncMKw==
2010-09-24T07:31:06.306Z





222
2010-07-14
Charles
Moulliard
Bla
Bla bla

cmoulliard@apache.org
0011 22 33 44





And finally, declare your camel route using the web services


















To play with the example, follow this example of Camel CXF and enjoy it !

Thursday, September 23, 2010

Fuse Community Day - Paris - 14th of October

The Fuse Community Day will take place the 14th of October in Paris. Feel free to sign up here and come to see Claus Ibsen, Guillaume Nodet, Rob Davies and myself presenting news about OSGI, SOA, Camel and ESB and some of our customers showing that in action (Lionel Cons - CERN, Cédric Bourgeois - Atos Worldwide, Jean Folly-Kpodar - Osmocom).

Friday, June 18, 2010

Parse / Format fixed length message with camel-bindy

Camel-bindy which is a data formatting tool to parse / format non XML message will be enriched in the next camel release 2.4. This new version will allow to work with Fixed Length message.

A Fixed Length message as its name mention it contains data positioned at a fixed position which is by far different from Comma Separate Value format where we use a separator.

So, you will be able able to model your message like that :


@FixedLengthRecord(length=60, paddingChar=' ')
public static class Order {

@DataField(pos = 1, length=2)
private int orderNr;

@DataField(pos = 3, length=2)
private String clientNr;

@DataField(pos = 5, length=9)
private String firstName;

@DataField(pos = 14, length=5, align="L")
private String lastName;

@DataField(pos = 19, length=4)
private String instrumentCode;

@DataField(pos = 23, length=10)
private String instrumentNumber;

@DataField(pos = 33, length=3)
private String orderType;

@DataField(pos = 36, length=5)
private String instrumentType;

@DataField(pos = 41, precision = 2, length=7)
private BigDecimal amount;

@DataField(pos = 48, length=3)
private String currency;

@DataField(pos = 51, length=10, pattern = "dd-MM-yyyy")
private Date orderDate;



to parse/format the following text :

"10A9 PaulineM ISINXD12345678BUYShare2500.45USD01-08-2009"

The tool allows to add 'padding' characters and to align "LEFT" or " RIGHT" the string in the field.

More info are available on the wiki web page of camel-bindy : http://camel.apache.org/bindy.html

Tuesday, March 30, 2010

Run Camel route on ServiceMix 3.3.x

Even if Apache ServiceMix (ESB) was mainly designed as a JBI container, it is perfectly possible to use camel routes and camel components (bindy, file, jms, ...) on this platform.

This allows by example to :
- Combine JBI binding components or Services with Camel routes,
- Use a camel component when the binding component does not exist,
- Deploy camel as Service Unit in Service Assembly

Here is a small example showing that in action. The creation of the project is very simple as you have to create a Service Unit. If you work with maven, you can use the servicemix plugin which will allow to create the maven project. Otherwise, you can create the maven structure manually.

To be able to deploy camel next, you must create a Service Assembly (= SA) who will include the Service Unit.

Don't be afraid and follow the tutorial described here for that part of the work : http://servicemix.apache.org/2-beginner-using-maven-to-develop-jbi-applications.html

When the project is ready, you create a camel-context.xml file in the directory src/main/resources. This file which is a spring xml file will contain the camel routes + beans definitions or will point to your packages if you prefer to code your routes using Camel Java DSL language instead of Spring DSL language.

Remark : in my example, I use Spring DSL language.

The route is very basic and will create a message containing the text "Hello World from SMX3!" as body value. The message is copied in an activemq queue called "in". A second route take the messages and send it to the log. The log message is readable from the console where ServiceMix 3.3.x has been started.

In the Spring file, you must add the camel bean "org.apache.camel.component.jms.JmsComponent" definition to instantiate a connection factory to the queueing engine. The broker is created and started at the launch of ServiceMix3 so you don't need to do anything else here !


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">










org.apache.servicemix.samples




Hello World from SMX3 !













To allow Camel to work with its jms component, the following dependency must be added in the pom of the camel-su.





org.apache.camel
camel-core
2.2.0


org.apache.camel
camel-spring
2.2.0


org.apache.camel
camel-jms
2.2.0






To compile the project, simply launch the command "mvn install" to generate the SU and do the same for the SA. When the Service Assembly jar file is available, copy it in the hotdeploy directory of ServiceMix 3 server and check the log.

This example which is very basic can be extended with another camel components. In that case, don't forget to add their dependency in the SU pom as the camel lib must be added in the lib directory of the SU.

Have fun with that !

Friday, February 26, 2010

Is Webservice Reliable Messaging (WS-RM) the ugly duck of the WS-* story ?

The Webservice Reliable Messaging (WS-RM) specification has been designed a couple of years ago (2005) but few projects used it. Different reasons could explain this situation, the complexity of the specification, the cost to implement it and the lack of use cases. Personally, I think that developers and architects adopt a low profile when designing a solution and spend times developing alternative solutions providing functionality similar to what WS-RM propose.

WS-RM is not a the ugly duck of the story and need more attention from community because it allows you to design solutions where you will be able to
- Guaranty of message (= web services) delivery required by example in financial order processing, alarm monitoring systems, ...
- Control the communication between the client and the server (retransmission, ...)
- Implement asynchronous solution by decoupling the request from the reply

Well, what I have presented could be assimilated to a style exercise or a faith act and you will adhere or not. To convince you about the interests to use WS-RM, I will show you How easy it is to design such a solution using Apache CXF framework. This process can be achieved in three simple steps

  • A. Turn on your WSDL contract into a WS-addressing

WS-addressing needs to be used because the communication between the client and server will be governed by the Reliable Message Server which is running on a different
port address number. This decoupling is required to allow to retransmit message, acknowledge the messages received and guaranty the delivery

Here is one way that you can adopt :












the other consists in to use a Policy Rule (= WS-Policy)









  • B. Activate the Reliable Server

Now that the WSDL contract is modified, we need to add the Reliable Server to the configuration of our platform. I will show you using a spring xml configuration file
but you can use the Apache CXF classes in your java code if you want

To activate the RM server, you simply needs to add the tags wsa:addressing and wsrm-mgr in the bus definition of Apache CXF. Different parameters are available like
retransmission interval, acknowledge interval. I will not digg into these ones and if you need information, I invite you to check Apache CXF javadoc and specifications. By example
ikt is possible to activate also the persistence manager of the RM server ;-)



















If you use CXF in combination with the Routing engine Apache Camel, you don't need to do additional things as the Apache CXF endpoint who will consume the web servicesmessages
will be drived by the RM server of CXF.

Here is an example of Camel integration with CXF









// messages are consumed from CXF endpoint
// the body of the WS message is converted directly into a POJOI
// We call a POJO to save the reportincident in a DB
// We put the object in a queue

// We provide a feedback message as the WS is of type request/replyt






  • C. Verify

If you use a java client using Apache CXF java classes, you can easily enable the logging of the IN/OUT WS messages exchanged with the RM server and the application.
The following trace shows that :
- a sequence has been started
- each message is identified '' with a UID
- Within a sequence, the messages send receive a messageID
- The server acknowledge the reception (= processing) of the messages



  • Conclusion

Awesome, isn'it. Even, if you continue to doubt about this specification, I'm pretty sure that in the future you will take it into account into your decision process regarding
to what has been developed here.