Sergey Beryozkin

Authentication and Authorization the CXF Way

Sergey Beryozkin - Fri, 12/17/2010 - 14:16
I've been working recently on a number of tests and a demo showing how CXF endpoints can be protected by having consumers relying either on Basic Authentication or WS-Security UsernameTokens authenticated and the authorization rules enforced.

Often enough, when confronted with the problem of making sure the authentication and the authorization works, many users think of using either the J2EE-style authentication (configured via web.xml) or Spring Security.

The former option does not really work with WS-Security and sometimes may not be easy to configure in a fine-grained fashion, besides one may want to defer the role verification until just before the actual invocation occurs. The latter option can let you do it all, given how advanced the Spring Security is. If you're a Spring Security savvy person then wiring it in to secure the endpoints against some arbitrary WS-Security tokens can be a child's play :-) but one have to admit that it might be a bit 'intimidating' sometimes and in some cases Spring is simply not used in a given project. Additionally, making it work in OSGI may present quite a challenge on its own.

The other thing I've heard of is that users dealing with WS-Security may not necessarily want to deal directly with the WSS4J library at the level of their CXF interceptors (by the way, please subscribe to the Colm's blog for more information about WSS4J and other security-related thoughts and updates).

So in the end a number of CXF security interceptors has been introduced to make it as easy as possible for CXF users to secure the endpoints at the authentication and authorization levels.

Additionally, a CXF-specific UsernameToken has been introduced which at the moment encapsulates the information obtained from the WSS4J UsernameToken.
As you can see, it implements the SecurityToken interface with the idea being that more token types will be supported in time. For example, an AbstractSecurityContextInInterceptor converts a token to a CXF SecurityContext instance by delegating to subclasses which know about a current token type, with
AbstractUsernameTokenInterceptor being one such subclass. In the end, say a concrete AbstractUsernameTokenInterceptor implementation only sees CXF UsernameToken which it needs to use somehow for authenticating and populating a current Subject.

The Subject instance will be wrapped in a CXF SecurityContext which will be used later on to do the authorization or further wrapped by JAX-RS or JAX-RS SecurityContext objects and injected into service beans. You may want to use SimplePrincipal and SimpleGroup helpers if needed when creating custom Subjects.

Note that CXF ships two SecurityContext implementations which attempt to figure out which Subject Principals are roles. DefaultSecurityContext assumes Group instances represent primitive or group roles, while RolePrefixSecurityContextImpl find the Principals by checking if their names start from the configurable role prefix, example, from "ROLE_" (this post has some more information).

So far so good - the authentication has been taken care of if you use WS-Security. If you don't them the authentication will occur earlier on at the container entry level, with or without SpringSecurity involved. However, after working on the container-level authentication demo last week it became apparent that CXF needs a utility JAASLoginInterceptor. You only need to tell it the name of the LoginContext to resolve and optionally provide a role prefix name in case Subject does not use Groups to represent the roles. You may also need to override its getCallbackHandler method returning NamePasswordCallbackHandler instances by default, for example, this custom interceptor ensures it can handle Jetty ObjectCallbacks for setting the password.

Another good news is that the JAASLoginInterceptor will work equally well with CXF UsernameTokens (created during WS-Security-related requests) and AuthorizationPolicy capturing Basic or Digest authentication details.

Next we may need to enforce the authorization rules. SimpleAuthorizingInterceptor can be injected with a method names to roles map, while SecureAnnotationsInterceptor takes it one step further and lets users just inject a reference to a secured object and it will figure out how individual methods are supposed to be secured; it checks RolesAllowed annotations by default but one can provide the annotation class name used to specify the roles.
If you have roles stored in say the database then you may want to extend AbstractAuthorizingInterceptor and override its getExpectedRoles method.

If you are securing JAXWS or JAXRS endpoints, you only need to add one or two interceptors, say an optional JAASLoginInterceptor and SimpleAuthorizingInterceptor. When securing JAX-RS endpoints with these interceptors you may also want to add a custom CXF out fault interceptor, for example, like this one, if you want 403 or 401, instead of 500 being returned; alternatively you can let the exception propagate up to the servlet level when possible and deal with the ServletExceptions at the filter levels.

The JAX-RS frontend also ships two utility filters wrapping JAASLoginInterceptor and both authorization interceptors, The one which wraps the JAASLoginInterceptor returns 401 by default and adds a realm name to the WWW-Authenticate response header if needed. It also lets users specify the resource URI where the client needs to be redirected to instead of getting 401. If needed a simple subclass can ensure unrecognized callbacks are dealt with the same way it's done with JAASLoginInterceptor. Here is a sample filter .

Finally, some more information on how to configure the interceptors. Have a look at this beans.xml. The test assumes the authentication is managed by the container, for example, one can configure a Maven Jetty plugin to enforce it. The web.xml requests the authentication only and see how SimpleAuthorizingInterceptor and SecureAnnotationsInterceptor are set up to do the rest - the authorization.

This beans.xml introduces the JAASLoginInterceptor (and the JAX-RS filter) into the picture. I think it would be fare to say it is simple to setup both the JAAS authenticator and the authorization filters in CXF. And guess what - this very configuration can make your application secure without changing a bit in the standalone server, the servlet container and the OSGI container such as Karaf.

The varying part is ensuring the server/container sees the JAAS configuration such as this one (FYI, "BookLogin" is the name injected into JAASLoginInterceptor, while BookLoginModule is wrapping a Jetty PropertyFileLoginModule).

In my test I'm passing a system property "java.auth.security.login.config" to the test server process. In Karaf one needs to deploy a bundle containing the JAAS config. The bottom line is that the issue of bootstrapping the server with this information is an issue of its own.

So what do you do in the end once you set these new CXF interceptors ? You can just relax and see your secure CXF application working like a charm irrespectively of where it is deployed to :-)

Enjoy !



Categories: Sergey Beryozkin

Talend Service Factory Examples

Sergey Beryozkin - Fri, 12/17/2010 - 12:17
As Dan has already mentioned, we have created a number of documented examples which have been tuned to run within the OSGI Karaf container shipped as part of the Talend Service Factory release.

The OSGI container in the release is really an optimized OSGI-aware Web Services stack with only the most relevant bundles being loaded. We've also tried to take care of minor issues such as ensuring that the default HTTP port is 8080 and that the HttpService context is set to "/services" by default as opposed to "/cxf". You can set these initial settings in 30 seconds yourself - but don't you want the demos just to work without having to know how to configure pax web and cxf osgi properties from the very start :-) ?

We have some serious plans to make sure CXF plays really well in OSGI - please keep an eye on the CXF dev list. We will want to make sure the CXF services and indeed the consumers just work in OSGI.

Additionally, most of the examples provide options for starting the services from the command line and within the servlet container.

Next I'd like to actually spend a bit of time and describe what examples we ship. What we have now is some classical CXF examples, such as the one demonstrating all sorts of CXF interceptors in action and additionally prepared to run in the OSGI container. The OSGI-fied example demonstrating SOAP over JMS specification is also there.

Finally we have started closing the gap which has existed in the area of JAX-RS demos and we've added 6 new demos.

Two first demos are called jaxrs-intro and jaxrs-advanced with the idea to show the basic JAX-RS features and then progress to a more involved example, not only showing more sophisticated JAX-RS features but also applying them to solving a reasonably interesting problem, traversing the Person family tree in a number of ways and updating individual Persons. These demos will be regularly updated.

The next 2 demos, jaxrs-jaxws-java-first and jaxrs-jaxws-description-first show how SOAP and RESTful services can be combined.
The first one shows how both JAX-WS and JAX-RS annotations can be combined on a single interface, how endpoints can share the same service bean and how both JAX-WS and CXF JAX-RS proxies can effectively use the same code for invoking on the services. The second one shows how SOAP services developed using a WSDL-first approach can be selectively exposed as RESTful services by applying an external CXF-JAXRS user model giving that modifying the interface generated from WSDL is not an option.

What we actually want to show with these 2 demos is that making this experience as seamless as possible is a top priority for us - we do want users to really like developing both SOAP and RESTful services with CXF.

The next demo, jaxrs-jms-http, shows how a typical JAX-RS HTTP server can be enhanced to receive the JMS messages with just adding few extra lines to the configuration. As noted here, you may want to do it if you'd like to preserve your investment in the JAX-RS but also make sure the service is capable of getting the messages from a variety of (transport) channels. This demo also shows how HTTP requests can be processed oneway with the server picking up the messages and forwarding them further to the JMS destination.

The last example is jaxrs-jaxws-authorization. This example shows CXF authentication and authorization interceptors in action, authenticating the users via JAAS and populating the CXF SecurityContext with Principal and its roles, and then enforcing the authorization rules for both JAX-WS and JAX-RS endpoints. The JAAS interceptor is only used when the demo is run within Karaf so that the Karaf JAAS context can be resolved. When the demo is deployed into the servlet container, the container-managed authentication is utilized to populate the current Principal.

This demo will be significantly simplified in the next release due to the recent related CXF enhancements (the topic of the next post).

You'll see many more examples added in time.

So please download the examples and give them a try. Note, you have to register in order to download the examples, this is due to the fact the examples content in general is considered to be a premium content at Talend, hopefully it won't be a problem for those who are interested.
Categories: Sergey Beryozkin

Change the world and go home

Sergey Beryozkin - Fri, 12/17/2010 - 11:38
I recall I was reading the Change the world or go home post from Dare Obasanjo and being a bit confused not about the content (which was interesting and thought provoking as usual) but about the 'or' bit in the subject.

I was asking myself, would it make sense to say "Change the world *and* go home" :-) ? I believe all of us working with the Open Source are changing the world every day, then we go home in the end of the day, and then we are back at it the next day, changing the world with our individual contributions, negligible in the scope of the big picture.

Of course, "or" had the meaning in the Dare's post. But I kind of like 'and' more :-)
Categories: Sergey Beryozkin

Sopera opens the development center in Ireland

Sergey Beryozkin - Thu, 11/18/2010 - 11:13
Last week myself and my colleague Colm stepped in into an office that Sopera secured for us in Dublin, Ballsbridge. We can nearly see the IONA Building we used to go to not that long ago from our place. The view from its window is really nice.

We are delighted. Being able to get to the office and work with and talk to your colleagues but also work from home on a given day is the ideal situation for software engineers and it really does feel it is the beginning of the new journey for us, with the only way ahead from here - onwards, especially now that Sopera has been acquired by Talend.
Categories: Sergey Beryozkin

CXF Auto Redirect Feature in action

Sergey Beryozkin - Mon, 11/15/2010 - 18:08
I was working today on testing some CXF JAX-RS client code against Tomcat and Jetty servers. All was going well with Tomcat : after deploying a sample.war to Tomcat and doing :


WebClient wc = WebClient.create("http://localhost:8080/sample";
wc.getCollection(Book.class);
// print the collection


a collection of Books was printed in the console.

However this code stopped working once I deployed a sample.war to Jetty, using a Maven Jetty plugin. I spent some good few hours debugging it before I spotted that Jetty returns HTTP 302 to a "GET /sample" request with the Location header pointing to "http://localhost:8080/sample/", note the trailing slash.

So changing the code to


WebClient wc = WebClient.create("http://localhost:8080/sample/";
wc.getCollection(Book.class);


made it work for both Tomcat and Jetty deployments. One other option to deal with the redirects is to use one of the WebClient methods returning JAX-RS Response rather than a typed one, and check the status and then follow the new URI if needed.

But I found the following code working nicely in the end :


WebClient wc = WebClient.create("http://localhost:8080/sample";
WebClient.getConfig(wc).getHttpConduit().getClient()
.setAutoRedirect(true);
wc.getCollection(Book.class);
Categories: Sergey Beryozkin

Being at ApacheCon 2010

Sergey Beryozkin - Mon, 11/08/2010 - 17:48
I got a chance to attend to the Apache Conference in Atlanta last week thanks to Sopera organizing this trip. It was the first time I was at the ApacheCon, and it was an interesting and unique experience.

First, Sopera had a workshop during the first 2 days of the week, before the conference started, so it was a good opportunity for many of us in the OS team to meet each other and we had some interesting discussions along the way.

ApacheCon brings together an interesting mix of people, some of them having the commercial interest, some representing large commercial and government organizations adopting OS, and some working on OS projects because this is what they really like doing on their own time.

It was interesting to listen to some technical talks. And meeting new people and seeing the former colleagues I used to work with (with some of them I will be working again from now on :-)) was great. And of course, meeting CXF legends such as Glen and Benson was another highlight :-).
Categories: Sergey Beryozkin

Give us your headaches

Sergey Beryozkin - Wed, 10/27/2010 - 18:24
Have I already mentioned that I liked reading the Richard Branson's auto-biography ?

I honestly think it was a gem of a book which I picked up in the Gatwick airport on the way to Dublin from Minsk. That is a story about the life journey told with a lot of humor, filled with some absolutely hilarious accounts of various events and with some very serious thoughts about doing business and contributing to saving the humanity.

You might want to ask, what is it all to do with the web services or software development given this post is not marked with [OT] ?

During his student days, Richard set up the Student Advisory Centre which consulted students on all the issues they could have, free of charge. One of their slogans was "Give us your headaches". This centre still operates today.

I thought, when I was reading about it, that to some extent, this is what the OS business model was partly about. In OS we are working on projects such as CXF and we are determined to make it all work really well, without any headaches, in the most demanding environments.

The OS business model is partially about providing the insurance that customers will experience no headaches when running such OS-driven projects in their productions. In fact this model has been proven very successful, by such top companies such as RedHat for example.

Are you considering to start using CXF but a bit concerned what will happen further down the road with all the OS development going on into it ?

Give us your headaches :-)
Categories: Sergey Beryozkin

CXF : Here we come !

Sergey Beryozkin - Wed, 10/27/2010 - 17:59
I'm happy to confirm that after a short break I'm going to have a chance to resume working on CXF and its JAXRS project in particular.

I'll join Dan and the rest of the Sopera OS team and we will be determined as ever to bring you the best production-quality web services framework around.

And with your help we will make the CXF users and dev lists the "hippiest place to be", the phrase is borrowed from a Richard Branson's auto-biography.

CXF won't be the only effort we will focus in Sopera but it is going to be one of the main ones.

Stay tuned.
Categories: Sergey Beryozkin

Goodbye JBoss

Sergey Beryozkin - Wed, 10/27/2010 - 16:57
So after less than 6 months after starting to work for JBoss I decided to quit and accept an offer from Sopera. In hindsight, I'm thinking that talking about the career publicly is not always the very best idea - spending such a short period of time at one of the leading company in the industry is not something that will improve my CV.

Back in April/May I was indeed looking forward to that great opportunity and it was not a stop-gap measure by any means. But CXF and CXF JAXRS are calling me back - it is next to impossible to resist. I'll blog about it next but this post is about JBoss and I'd like to talk about it a bit.

Just 6 months ago I had a fairly vague idea about what JBoss were doing, apart from knowing that they were part of RedHat, that it was an application server and that their JBossWS project was providing a CXF JAXWS integration option. And of course I knew about RestEasy.

In the reality, JBoss is a very live, active and progressive project, with a lot of very clever and innovative people working on it and who are really passionate about JBoss. And they have a very open and democratic environment with everyone being able to express their thoughts aloud.

I've promised in my previous post I'd link to various JBoss subprojects. Here are the links to some of them :

JBossWS : Web Service Framework for JBoss AS
RestEasy : JAX-RS implementation with various features
PicketLink : STS, etc
JBossTS : While many are saying that WS transactions support is next to impossible to provide this team just does it
HornetQ : Putting the buzz in messaging


As far as I'm concerned it is obvious I've given away the real opportunity with a great company. That said, the life is about many opportunities, and I'm about to pursue the new and exciting one, with the young and innovative company.

Goodbye JBoss, Hello Sopera !
Categories: Sergey Beryozkin

Pages

Subscribe to Talend Community Coders aggregator - Sergey Beryozkin