Apache CXF Client- Setting Http Request Header for Basic Authentication

Home / Blog / Java / Apache CXF Client- Setting Http Request Header for Basic Authentication

While setting up Test Driven Development environment with Apache CXF, I came across a small issue with creating a JUnit client, which will add the Basic Authentication info in the Http Request Header before sending the request. I found couple of ways to do this using JAXWS, but wanted to stick with Apache CXF.
On the Server side, I was using Spring Security which was not so tricky to configure. To add the header info, I needed to create an “Interceptor”, which will intercept the message before it is “marshalled”. Here is the code –

 
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
import org.springframework.beans.factory.annotation.Required;
 public class BasicAuthenticationHeaderGeneratorInterceptor extends
		AbstractOutDatabindingInterceptor {
	public static final String COLON = ":";
	public static final String SPACE = " ";
	public static final String BASIC = "Basic";
	/** Map of allowed buy yasmin online cheap users to this system with their corresponding passwords. */
	private Map users;

	@Required
	public void setUsers(Map users) {
		this.users = users;
	}

	public BasicAuthenticationHeaderGeneratorInterceptor() {
		super(Phase.MARSHAL);
	}

	public BasicAuthenticationHeaderGeneratorInterceptor(String phase) {
		super(phase);
	}

	public void handleMessage(Message outMessage) throws Fault {
		Map<String, List> headers = (Map<String, List>) outMessage
				.get(Message.PROTOCOL_HEADERS);
		try {
			headers.put("Authorization", Collections.singletonList(BASIC
					+ SPACE + getBase64EncodedCredentials().trim()));
		} catch (Exception ce) {
			throw new Fault(ce);
		}
	}

	private String getBase64EncodedCredentials(){
		String userName = null;
		String password = null;
		Iterator iterator = null != users ? users.keySet().iterator()
				: null;
		if (null != iterator && iterator.hasNext()) {
			userName = iterator.next();
			password = users.get(userName);
		}
		String clearCredentials = userName + COLON + password;
		return new String(Base64.encodeBase64(clearCredentials.getBytes()));
	}
}

Here is the interceptor configuration in application-context.xml –

 
  <cxf:bus>
		<cxf:outInterceptors>
			<ref bean="basicAuthenticationHeaderGenerator" />
		</cxf:outInterceptors>
  </cxf:bus>

  <bean id="basicAuthenticationHeaderGenerator"
	class="com.blah.interceptor.BasicAuthenticationHeaderGeneratorInterceptor">
		<property name="users">
			<map>
				<entry key="abc" value="dev" />
			</map>
		</property>
	</bean>

I preferred this implementation over JAXWS, since it works great with Spring Test and Apache CXF, without having to use JAXWS API.

Leave a Comment