Customize ATG Web Service to include
Security
ATG
by default do not provide to include SOAP header security in Webservices. Thus
we need to customize ATG SOAP webservice to read header. Also it is not
possible to read headers from request in our custom webservice component. Thus
we need to customize below components and Read the Headers from Web Service
calls.
·
Override WebserviceGenerator component, create a custom class and Override method addWSDLImportFilter to add out custom filter.
public class CustomWebserviceGenerator extends
WebServiceGeneratorImpl {
protected void addWSDLImportFilter(String
pWebAppFactoryName,
WebApp
pWebApp, String pServletName) throws
JAXBException {
List
filters = pWebApp.getFilter();
boolean found = false;
Iterator
filterIter = filters.iterator();
while
(filterIter.hasNext()) {
FilterType
filter = (FilterType) filterIter.next();
FilterClassType
filterClass = filter.getFilterClass();
if
(filterClass.getValue()
.equals("com.custom.filter. CustomWSDLImportFilter")) {
found
= true;
}
}
if
(!(found)) {
appendFilterToWebAppDD(pWebAppFactoryName,
pWebApp,
"com.custom.filter.CustomWSDLImportFilter", "
customWSDLImportFilter");
}
String
mapping = "/" + pServletName + "/*";
appendFilterMappingToWebAppDD(pWebAppFactoryName,
pWebApp,
"CustomWSDLImportFilter",
mapping);
}
}
·
Re-Create WebService EAR file. Now the
web.xml in the custom module will include our custom filter.
·
Write CustomWSDLImportFilter
class to read header with the help of MultiReadHttpServletRequest
public class CustomWSDLImportFilter extends
WSDLImportFilter {
public CustomWSDLImportFilter()
{
super();
}
public void
doFilter(ServletRequest paramServletRequest,
ServletResponse
paramServletResponse, FilterChain paramFilterChain)
throws
IOException, ServletException {
RepositoryItem
userProfileItem = null;
SOAPMessageContext
messageContext = new SOAPMessageContext();
MimeHeaders
headers = getHeaders((HttpServletRequest) paramServletRequest);
MultiReadHttpServletRequest
multiReadRequest = new MultiReadHttpServletRequest(
(HttpServletRequest)
paramServletRequest);
try {
javax.naming.InitialContext
ic = new javax.naming.InitialContext();
ProfileTools
profileTools = (atg.userprofiling.ProfileTools) ic
.lookup(EatonConstants.WS_JNDI_PROFILE_TOOLS);
if
(profileTools.isWebServiceHeaderRequired()) {
SOAPMessage
message = getSOAPMessageFromRequest(
(HttpServletRequest)
multiReadRequest, headers,
messageContext);
if
(message.getSOAPHeader() != null) {
Iterator
iter = message.getSOAPHeader()
.extractAllHeaderElements();
while
(iter.hasNext()) {
SOAPHeaderElement
headerEl = (SOAPHeaderElement) iter
.next();
if
(headerEl.getElementsByTagName(
EatonConstants.WS_USERNAME).item(0)
!= null) {
userName
= headerEl
.getElementsByTagName(
EatonConstants.WS_USERNAME).item(0)
.getTextContent();
}
if
(headerEl.getElementsByTagName(
EatonConstants.WS_PASSWORD).item(0)
!= null) {
password
= headerEl
.getElementsByTagName(
EatonConstants.WS_PASSWORD).item(0)
.getTextContent();
}
}
System.out.println(“username
: ” + userName);
System.out.println(“password: ” +
password);
}
else {
throw new
SecurityException(
EatonConstants.WS_HEADER_MISSING);
}
}
} catch
(SOAPException soapExeception) {
//
return;
} catch
(NamingException NamingException) {
return;
}
super.doFilter(multiReadRequest,
paramServletResponse, paramFilterChain);
}
protected static
MimeHeaders getHeaders(HttpServletRequest req) {
Enumeration
enums = req.getHeaderNames();
MimeHeaders
headers = new MimeHeaders();
while
(enums.hasMoreElements()) {
String
headerName = (String) enums.nextElement();
String
headerValue = req.getHeader(headerName);
headers.addHeader(headerName,
headerValue);
}
return headers;
}
protected
SOAPMessage getSOAPMessageFromRequest(HttpServletRequest request,
MimeHeaders
headers, SOAPMessageContext messageContext)
throws
IOException {
SOAPMessage
message = null;
InputStream
is = request.getInputStream();
byte[] bytes
= readFully(is);
int length =
(request.getContentLength() == -1) ? bytes.length
:
request.getContentLength();
ByteInputStream
in = new ByteInputStream(bytes, length);
message
= messageContext.createMessage(headers, in);
return message;
}
protected static byte[]
readFully(InputStream istream) throws
IOException {
ByteArrayOutputStream
bout = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int num = 0;
while
((istream != null) && ((num = istream.read(buf)) != -1)) {
bout.write(buf,
0, num);
}
byte[] ret =
bout.toByteArray();
return ret;
}
}
·
MultiReadHttpServletRequest implementation
to read headers.
public class
MultiReadHttpServletRequest extends HttpServletRequestWrapper
{
private
ByteArrayOutputStream cachedBytes;
public
MultiReadHttpServletRequest(HttpServletRequest request) {
super(request);
}
@Override
public
ServletInputStream getInputStream() throws
IOException {
if (cachedBytes == null)
cacheInputStream();
return new
CachedServletInputStream();
}
@Override
public
BufferedReader getReader() throws IOException{
return new
BufferedReader(new InputStreamReader(getInputStream()));
}
private void
cacheInputStream() throws IOException {
/*
Cache the inputstream in order to read it multiple times. For
* convenience,
I use apache.commons IOUtils
*/
cachedBytes = new
ByteArrayOutputStream();
IOUtils.copy(super.getInputStream(),
cachedBytes);
}
/* An inputstream
which reads the cached request body */
public class
CachedServletInputStream extends ServletInputStream {
private
ByteArrayInputStream input;
public
CachedServletInputStream() {
/*
create a new input stream from the cached request body */
input = new
ByteArrayInputStream(cachedBytes.toByteArray());
}
@Override
public int read() throws
IOException {
return input.read();
}
}
}