Developers, Developers, Developers! Maksim Sorokin IT Blog

6Aug/11Off

Maven + Apache Felix + CXF: Securing a Service with HTTP Basic Authentication

This is another post in series Maven + Apache Felix + CXF + DOSGi Series. Here I will describe how to secure CXF published web services with HTTP basic authentication. You can find the sources on my GitHub account.

We will have three projects here. The first one defines an interface for a service. Another one provides implementation for it. And the third one will provide security.

dosgiSecurity
    dosgiSecurity-api
    dosgiSecurity-impl
    dosgiSecurity-security

dosgiSecurity will be just a holder project.

Our interface HelloService in bundle dosgiSecurity-api will be similar to the one we defined in previous posts:

package dk.sorokin.maksim.dosgiSecurity.api;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("helloService")
public interface HelloService {

  @GET
  @Path("sayHello/{name}")
  @Produces(MediaType.TEXT_PLAIN)
  String sayHello(@PathParam("name") String name);
}

And implementation class HelloServiceImpl in bundle dosgiSecurity-impl:

package dk.sorokin.maksim.dosgiSecurity.impl.internal.service;

import dk.sorokin.maksim.dosgiSecurity.api.HelloService;

public class HelloServiceImpl implements HelloService {

  public String sayHello(String name) {
    return "Hello " + name;
  }
}

And SecurityFilter in bundle dosgiSecurity-security, is just a servlet filter. It checks for Authorization header and verifies it:

package dk.sorokin.maksim.dosgiSecurity.impl.internal.service;

import dk.sorokin.maksim.dosgiSecurity.api.HelloService;

public class HelloServiceImpl implements HelloService {

  public String sayHello(String name) {
    return "Hello " + name;
  }
}

The service is published in an Activator in dosgiSecurity.impl:

package dk.sorokin.maksim.dosgiSecurity.impl.internal;

import java.util.Dictionary;
import java.util.Hashtable;

import javax.servlet.Filter;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

import dk.sorokin.maksim.dosgiSecurity.api.HelloService;
import dk.sorokin.maksim.dosgiSecurity.impl.internal.service.HelloServiceImpl;
import dk.sorokin.maksim.dosgiSecurity.security.SecurityFilter;

public class Activator implements BundleActivator {

  public void start(BundleContext context) throws Exception {
    Dictionary<String, String> restProps = new Hashtable<String, String>();

    restProps.put("service.exported.interfaces", "*");
    restProps.put("service.exported.configs", "org.apache.cxf.rs");
    restProps.put("service.exported.intents", "HTTP");
    restProps.put("org.apache.cxf.rs.httpservice.context", "/secured");
    restProps.put("org.apache.cxf.rs.address", "http://localhost:8080/");
    context.registerService(HelloService.class.getName(), new HelloServiceImpl(), restProps);

    Dictionary<String, String> filterProps = new Hashtable<String, String>();
    filterProps.put("org.apache.cxf.httpservice.filter", Boolean.TRUE.toString());
    filterProps.put("servletNames", "none");
    context.registerService(Filter.class.getName(), new SecurityFilter(), filterProps);
  }

  public void stop(BundleContext context) throws Exception {
    //
  }
}

And a Felix Launcher (refer to the first post in series) is:

felix.auto.deploy.action=install,start
felix.log.level=1

org.osgi.framework.storage.clean=onFirstInit

felix.auto.start.1 = \
 assembly:/C:/projects/dosgiSecurity/dosgiSecurity.security/target/classes \
 assembly:/C:/projects/dosgiSecurity/dosgiSecurity.api/target/classes \
 assembly:/C:/projects/dosgiSecurity/dosgiSecurity.impl/target/classes

Now build all that with Maven using mvn clean install and run it (assuming that you have DOSGi Single Bundle Distribution in Felix, as we discussed in previous posts). When Felix is launched, go to http://localhost:8080/secured/helloService/sayHello/Max. You should see:

HTTP ERROR: 403

FORBIDDEN
RequestURI=/secured/helloService/sayHello/Max

Powered by Jetty://

Now launch Fiddler2 (or similar program) and build custom request with Request Builder with the same url as shown above. And add the following line in "Request Headers":

Authorization: Basic U3V6eTpyb2NrZXQ=

You should get:

HTTP/1.1 200 OK
Content-Type: text/plain
Date: Tue, 02 Aug 2011 15:15:43 GMT
Content-Length: 9
Server: Jetty(6.1.x)

Hello max

Source files can be found here

Comments (0) Trackbacks (0)

Sorry, the comment form is closed at this time.

Trackbacks are disabled.