Rajnish Kumar [
https://community.jboss.org/people/rajnish.kumar.76] created the document:
"Client Side Authentication in HTTP Gateway "
To view the document, visit:
https://community.jboss.org/docs/DOC-19730
--------------------------------------------------------------
*Dear All,
I had to do this for my project. If any one of you have this requirement then you can use
it.
Environment Details :-
Consumer on HTTPs with client auth enabled
web server (apache or can be anything)
app server (Jboss ESB +++++) [I was using SOA-P 5.2]
Issue :-
httpgateway (basically a listener) can't get client cert to authenticate the details
of the customer.
Descritption, short coming and Solution :-
Basically problem lies in the layer where HTTP request with all it's header is passed
to the action chain in the service where typicaly your gatewaty is httpgateway.
<http-gateway name=++"HTTP-Gateway".....++
Internally it uses few classes. Of particular interest to us are two classes which is used
and needs to be customized to meet the need.
org.jboss.soa.esb.listeners.gateway.http.HttpMessageComposer
org.jboss.soa.esb.listeners.gateway.http.HttpRequestWrapper
*
Changes that you will need to are following :-
[1] Instruct ESB service to use your custom message composer class
[2] Create a custom message composer class
[3] Create a custom HttpRequestWraper class which can handle attributes, http headers and
locales (what ever you need is, not necessary to handle everything)
Steps in details
[1] Instruct ESB service to use your custom message composer class
Modify your jboss-esb.xml file and add below statement as part of <http-gateway>
tag
<property name="composer-class"
value="esb.gateway.CustomHttpMessageComposer"/>
This tell the service to use the customized HttpMessageComposer
[2] Create a custom message composer class
package esb.gateway;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.jboss.soa.esb.http.HttpHeader;
import org.jboss.soa.esb.http.HttpRequest;
import org.jboss.soa.esb.listeners.gateway.http.HttpMessageComposer;
import org.jboss.soa.esb.listeners.gateway.http.HttpRequestWrapper;
public class CustomHttpMessageComposer<T extends HttpRequestWrapper> extends
HttpMessageComposer<T>{
private static final Logger logger = Logger.getLogger(CustomHttpMessageComposer.class);
@Override
/*
* this is the only method you need to override.
* make it return your custom httprequest class which can handle attributes and headers and
locale
* retain all the original functionality by calling the super class method
*/
public CustomHttpRequest getRequestInfo(HttpServletRequest request) {
logger.info("co.za.fnbwealth.esb.gateway.CustomHttpMessageComposer
getRequestInfo() called");
HttpRequest requestInfo = super.getRequestInfo(request);
CustomHttpRequest customRequestInfo = new CustomHttpRequest(requestInfo);
//Copy the attributes. This will have cert info
Enumeration attrNames = request.getAttributeNames();
while(attrNames.hasMoreElements()){
String attrName = (String)attrNames.nextElement();
Object val = request.getAttribute(attrName);
customRequestInfo.setAttribute(attrName, val);
}
//Copy Headers
Enumeration hdrNames = request.getHeaderNames();
List<HttpHeader> hdrs = customRequestInfo.getHeaders();
while(hdrNames.hasMoreElements()){
String hdrName = (String)hdrNames.nextElement();
String hdrVal = request.getHeader(hdrName);
HttpHeader hdr = new HttpHeader(hdrName, hdrVal);
hdrs.add(hdr);
}
//Copy Locale
customRequestInfo.setLocales(request.getLocales());
return customRequestInfo;
}
}
[3] Create a custom HttpRequestWraper class
package esb.gateway;
import java.io.Serializable;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.jboss.soa.esb.http.HttpRequest;
public class CustomHttpRequest extends HttpRequest implements Serializable{
private static final Logger logger = Logger.getLogger(CustomHttpRequest.class);
private X509Certificate clntCerts[];
private Map<String, Object> attrs = new HashMap<String, Object>();
//Locales implementation hasn't been tested including getter and setter for locales
private Enumeration locales;
/*
* In the costructor get all the values by making call to the super class
* Add getter and setter method for nea features you want
* Here methods have been added to handle attribute(cleint cert comes in this), http header
and locale
*/
public CustomHttpRequest(HttpRequest parent){
logger.info("co.za.fnbwealth.esb.gateway.CustomHttpRequest constructor
called");
super.setRemoteAddr(parent.getRemoteAddr());
super.setAuthType(parent.getAuthType());
super.setCharacterEncoding(parent.getCharacterEncoding());
super.setContentType(parent.getContentType());
super.setContextPath(parent.getContextPath());
super.setLocalAddr(parent.getLocalAddr());
super.setLocalName(parent.getLocalName());
super.setMethod(parent.getMethod());
super.setPathInfo(parent.getPathInfo());
super.setProtocol(parent.getProtocol());
super.setQueryString(parent.getQueryString());
super.setRemoteAddr(parent.getRemoteAddr());
super.setRemoteHost(parent.getRemoteHost());
super.setRemoteUser(parent.getRemoteUser());
super.setContentLength(parent.getContentLength());
super.setRequestSessionId(parent.getRequestSessionId());
super.setRequestURI(parent.getRequestURI());
super.setScheme(parent.getScheme());
super.setServerName(parent.getServerName());
super.setRequestPath(parent.getRequestPath());
super.setPathInfo(parent.getPathInfo());
}
public Object getAttribute(String attrName){
logger.info("co.za.fnbwealth.esb.gateway.CustomHttpRequest
getAttribute("+attrName+") called");
return attrs.get(attrName);
}
public void setAttribute(String attrName, Object value){
logger.info("co.za.fnbwealth.esb.gateway.CustomHttpRequest
setAttribute("+attrName+", "+value+") called");
attrs.put(attrName, value);
}
public void removeAttributeNames(String attrName){
logger.info("co.za.fnbwealth.esb.gateway.CustomHttpRequest
removeAttributeNames("+attrName+") called");
attrs.remove(attrName);
}
public Map<String, Object> getAttributes(){
logger.info("co.za.fnbwealth.esb.gateway.CustomHttpRequest getAttributes()
called");
return attrs;
}
public Enumeration getLocales(){
return locales;
}
public void setLocales(Enumeration locales){
this.locales = locales;
}
}
This is all that's required for this.
Finally note that you need to get and use customHttpRequest you have created in your
custom action where you want to inspect the client cert(or. anything you customized).
CustomHttpRequest req = (CustomHttpRequest)message.getProperties().getProperty(
"org.jboss.soa.esb.http.HttpRequest#request"
);
Good Luck !!!
Cheers,
-Rajnish
--------------------------------------------------------------
Comment by going to Community
[
https://community.jboss.org/docs/DOC-19730]
Create a new document in JBoss ESB Development at Community
[
https://community.jboss.org/choose-container!input.jspa?contentType=102&a...]