Web service soap header authentication - web-services

I have a web service, i want to authenticate the user from the soap header. That is, i want to check a token id (random number) in soap header and validate it against a value in my database and if the number matches i allow the request to go through otherwise i dont want to allow execution of my web method.
Is there any clean way of doing it using SOAP headers?
Thanks,
Mrinal Jaiswal

Have you looked into WS-Security? Assuming you're not already using it for something else, you could carry your token in the Username element, etc.
<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1">
<wsse:Username>yourusername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">yourpassword</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<yourbodygoeshere>
</soapenv:Body>
</soapenv:Envelope>

I created a web service using JDK API, and do a simple authentication by soap header.
This simple project provide two services:
login
get message from server
Client posts username and password in the soap body to server, if login successfully, the server will return a token in the soap header.
Clients calls getMessage service by including this token in the soap header, server check the token, if it is a logged in user, then return a success message, otherwise return a failed message.
The following is the code:
package com.aug.ws;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.WebParam.Mode;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.xml.ws.Holder;
//Service Endpoint Interface
#WebService
#SOAPBinding(style = Style.RPC)
public interface HelloWorld {
#WebMethod
void login(String userName, String password, #WebParam(header = true, mode = Mode.OUT, name = "token") Holder<String> token);
String getMessage(String message);
}
package com.aug.ws;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebParam.Mode;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.ws.Holder;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import com.sun.xml.internal.ws.api.message.Header;
import com.sun.xml.internal.ws.api.message.HeaderList;
import com.sun.xml.internal.ws.developer.JAXWSProperties;
#WebService(endpointInterface = "com.aug.ws.HelloWorld")
public class HelloWorldImpl implements HelloWorld {
private Map<String, String> authorizedUsers = new HashMap<String, String>();
#Resource
WebServiceContext wsctx;
#Override
#WebMethod
public void login(String userName, String password, #WebParam(header = true, mode = Mode.OUT, name = "token") Holder<String> token) {
if (("user1".equals(userName) && "pwd1".equals(password)) || ("user2".equals(userName) && "pwd2".equals(password))) {
String tokenValue = "authorizeduser1234" + userName;
token.value = tokenValue;
authorizedUsers.put(tokenValue, userName);
System.out.println("---------------- token: " + tokenValue);
}
}
#Override
#WebMethod
public String getMessage(String message) {
if (isLoggedInUser()) {
return "JAX-WS message: " + message;
}
return "Invalid access!";
}
/**
* Check token from SOAP Header
* #return
*/
private boolean isLoggedInUser() {
System.out.println("wsctx: " + wsctx);
MessageContext mctx = wsctx.getMessageContext();
HeaderList headerList = (HeaderList) mctx.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
String nameSpace = "http://ws.aug.com/";
QName token = new QName(nameSpace, "token");
try {
Header tokenHeader = headerList.get(token, true);
if (tokenHeader != null) {
String user = authorizedUsers.get(tokenHeader.getStringContent());
if (user != null) {
System.out.println(user + " has logged in.");
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
package com.aug.endpoint;
import javax.xml.ws.Endpoint;
import com.aug.ws.HelloWorldImpl;
public class HelloWorldPublisher {
/**
* #param args
*/
public static void main(String[] args) {
Endpoint.publish("http://localhost:9000/ws/hello", new HelloWorldImpl());
System.out.println("\nWeb service published # http://localhost:9000/ws/hello");
System.out.println("You may call the web service now");
}
}
package com.aug.client;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import com.aug.ws.HelloWorld;
import com.sun.xml.internal.ws.api.message.HeaderList;
import com.sun.xml.internal.ws.api.message.Headers;
import com.sun.xml.internal.ws.developer.JAXWSProperties;
import com.sun.xml.internal.ws.developer.WSBindingProvider;
public class HelloWorldClient {
private static final String WS_URL = "http://localhost:9000/ws/hello?wsdl";
private static final String NAME_SPACE = "http://ws.aug.com/";
public static String login() throws Exception {
URL url = new URL(WS_URL);
QName qname = new QName(NAME_SPACE, "HelloWorldImplService");
Service service = Service.create(url, qname);
HelloWorld hello = service.getPort(HelloWorld.class);
hello.login("user1", "pwd1", null);
WSBindingProvider bp = (WSBindingProvider) hello;
HeaderList headerList = (HeaderList) bp.getResponseContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
bp.close();
return headerList.get(new QName(NAME_SPACE, "token"), true).getStringContent();
}
public static void getMessage() throws Exception {
String token = login();
System.out.println("token: " + token);
URL url = new URL(WS_URL);
QName qname = new QName(NAME_SPACE, "HelloWorldImplService");
Service service = Service.create(url, qname);
HelloWorld hello = service.getPort(HelloWorld.class);
WSBindingProvider bp = (WSBindingProvider) hello;
bp.setOutboundHeaders(
Headers.create(new QName(NAME_SPACE, "token"), token)
);
System.out.println(hello.getMessage("hello world"));
bp.close();
}
public static void main(String[] args) throws Exception {
getMessage();
}
}

Related

How to stop user to add extra tag in SOAPUI request

Below is my SOAP request:
Aditya
?
My rest of the classes are:
HelloWorld.java
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
//Service Endpoint Interface
#WebService
#SOAPBinding(style = Style.RPC)
public interface HelloWorld{
#WebMethod String getHelloWorldAsString(String name, String company);
}
HelloWorldImpl.java:
import javax.jws.WebService;
import com.sun.xml.internal.ws.developer.SchemaValidation;
//Service Implementation
//#SchemaValidation
#WebService(endpointInterface = "org.techsavvy.HelloWorld")
public class HelloWorldImpl implements HelloWorld{
#Override
public String getHelloWorldAsString(String name, String company) {
return "Hello!! your name is " + name+ " and you work in " +company+ ".";
}
}
HelloWorldPublisher.java
import javax.xml.ws.Endpoint;
import org.techsavvy.HelloWorldImpl;
//Endpoint publisher
public class HelloWorldPublisher{
public static void main(String[] args) {
Endpoint.publish("http://localhost:9999/ws/hello", new HelloWorldImpl());
}
}
Problem: I am running my webservice in SOAPUI by adding the wsdl path(http://localhost:9999/ws/hello?wsdl). Once the request is generated I am entering the values for and and it runs successfully.
I want that if I am adding any extra tag to my generated request, response should not be generated and system should throw an error.
NOTE: I am not using any framework.

HTTP GET request with proper content-type is not hitting the expected service method

I have 2 restful service method getCustomerJson and getCustomerXML in a class CustomerResource where i am using jersey API for Restful Webservices. All the parameters of the 2 methods are same except one produces xml and other produces json.
When i am using the a HTTP GET request with header Content-Type="application/json" it always invokes the getCustomerXML method which returns xml.
Can someone explain me how jersey works in this kind of situation ?
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import domain.Customer;
#Path("/customers")
public class CustomerResource {
private static Map<Integer, Customer> customerDB = new ConcurrentHashMap<Integer, Customer>();
private static AtomicInteger idCounter = new AtomicInteger();
// Constructor
public CustomerResource() {
}
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayHello() {
return "Hello Kundan !!!";
}
#GET
#Path("{id}")
#Produces("application/xml")
public Customer getCustomerXML(#PathParam("id") int id, #Context HttpHeaders header) {
final Customer customer = customerDB.get(id);
List<String> contentList = header.getRequestHeader("Content-Type");
List<String> languageList = header.getRequestHeader("Accept-Language");
List<String> compressionFormatList = header.getRequestHeader("Content-Type");
if (customer == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return customer;
}
#GET
#Path("{id}")
#Produces("application/json")
public Customer getCustomerJson(#PathParam("id") int id) {
final Customer customer = customerDB.get(id);
if (customer == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return customer;
}
#POST
#Consumes("application/xml")
public Response createCustomer(Customer customer) {
customer.setId(idCounter.incrementAndGet());
customerDB.put(customer.getId(), customer);
System.out.println("Created customer " + customer.getId());
return Response.created(URI.create("/customers/" + customer.getId())).build();
}
#PUT
#Path("{id}")
#Consumes("application/xml")
public void updateCustomer(#PathParam("id") int id, Customer customer) {
Customer current = customerDB.get(id);
if (current == null)
throw new WebApplicationException(Response.Status.NOT_FOUND);
current.setFirstName(customer.getFirstName());
current.setLastName(customer.getLastName());
current.setStreet(customer.getStreet());
current.setCity(customer.getCity());
current.setState(customer.getState());
current.setZip(customer.getZip());
current.setCountry(customer.getCountry());
}
#DELETE
#Path("{id}")
public void deleteCustomer(#PathParam("id") int id) {
customerDB.remove(id);
System.out.println("Deleted !");
}
}
Use Accept: application/json. Accept tells the server what type you want back. Content-Type if for the type of data you are sending to the server, like with a POST request.

Can't get my REST web service to work (using Glassfish in Netbeans)

I'm writing a fairly simple restful web service project in Netbeans (used the Maven Web Application template). I am trying to run it on a Glassfish 4.1 server. I have used Tomcat in the past, but that's not really an option here. Basically, my problem is that I run the project, the server starts, but I just get a 404 error when I try to access the service in the browser.
Here is my source code:
package jp.go.aist.limrs;
import com.hp.hpl.jena.rdf.model.Model;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.websocket.server.PathParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.commons.io.IOUtils;
#Path("/target")
public class ParserService
{
public static final String SERVER_LOC = "http://localhost:8080/LiMRS/";
public static final String MAPPINGS_LOC = "export.txt";
private String targetUrl;
private String microData;
private Model uDataModel;
private Model mappingsModel;
public ParserService() {}
public ParserService( String url )
{
this.targetUrl = url;
try {
parseMicro(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
#GET
#Path("/{url:.+}")
#Produces(MediaType.TEXT_PLAIN)
public String getMicro(#PathParam("url") String target)
{
this.targetUrl = target;
String domain = "_";
try {
URI uri = new URI(this.targetUrl);
domain = uri.getHost();
System.out.println("Domain is " + domain + "\n\n\n");
} catch (URISyntaxException ex) {
Logger.getLogger(jp.go.aist.LiMRS.LiMRService.class.getName()).log(Level.SEVERE, null, ex);
}
this.microData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<rdf:RDF xml:base=\"http://dbpedia.org/ontology/\" " +
"xmlns:_=\"" + domain + "\">\n\n";
try
{
parseMicro(URLEncoder.encode(this.targetUrl, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
return "";
}
return this.microData;
}
private void parseMicro(String target) throws MalformedURLException
{
try {
URL url = new URL("http://getschema.org/microdataextractor?url=" + target + "&out=rdf");
HttpURLConnection conn;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
InputStream ins = conn.getInputStream();
StringWriter writer = new StringWriter();
IOUtils.copy(ins, writer, null);
this.microData += writer.toString() + ".";
} catch (IOException ex) {
Logger.getLogger(jp.go.aist.LiMRS.LiMRService.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (MalformedURLException ex) {
Logger.getLogger(jp.go.aist.LiMRS.LiMRService.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
The URL I'm using to test the service is: http://localhost:8080/LiMRS/target/http://www.rottentomatoes.com/m/jurassic_park/
(I know the URL is unencoded. There are forward slashes in the 'resource' part of the URL, after "/target/", but that is taken care of by the regex in the code and is not source of the problem.)
It's possible the problem is with the server itself, I don't know if there is any special configuration that needs to be done to Glassfish or if you can just run the project outright. I don't have a web.xml file. Unless I'm mistaken, I don't think I need one. What am I missing here?
You're going to need a web.xml or a Application/ResourceConfig subclass to configure the application. If you don't want to use a web.xml, the easiest thing you can do is have an empty Application class annotated with #ApplicationPath. This will cause the registration of all #Path classes you have
#ApplicationPath("/")
public class JaxRsApplication extends Application {}
You can see more options here

getting an error with webservices

Im doing restfull webservices with soap using websphere and RAD. After generating my javaclient classes when I run the test class I get the following error. Ive been searching the web but not finding the correct solution. PLEASE HELP!
ERROR:
Check method call
org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(Unknown Source)
at org.apache.xerces.dom.NodeImpl.appendChild(Unknown Source)
at com.ibm.ws.webservices.engine.xmlsoap.SOAPPart.appendChild(SOAPPart.java:282)
at com.sun.xml.internal.bind.marshaller.SAX2DOMEx.startElement(SAX2DOMEx.java:177)
at com.sun.xml.internal.ws.message.AbstractMessageImpl.writeTo(AbstractMessageImpl.java:159)
at com.sun.xml.internal.ws.message.AbstractMessageImpl.readAsSOAPMessage(AbstractMessageImpl.java:194)
at com.sun.xml.internal.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:80)
at test.CustomSoapHandler.handleMessage(CustomSoapHandler.java:37)
at test.CustomSoapHandler.handleMessage(CustomSoapHandler.java:1)
at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandleMessage(HandlerProcessor.java:293)
at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandlersRequest(HandlerProcessor.java:134)
at com.sun.xml.internal.ws.handler.ClientSOAPHandlerTube.callHandlersOnRequest(ClientSOAPHandlerTube.java:139)
at com.sun.xml.internal.ws.handler.HandlerTube.processRequest(HandlerTube.java:117)
at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:599)
at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:558)
at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:543)
at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:440)
at com.sun.xml.internal.ws.client.Stub.process(Stub.java:223)
at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:136)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:110)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:90)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:119)
at $Proxy33.getHistory(Unknown Source)
at test.ServiceTest.historyTest(ServiceTest.java:64)
at test.ServiceTest.main(ServiceTest.java:100)
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.J9VMInternals.initialize(J9VMInternals.java:227)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:90)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:119)
at $Proxy33.getHistory(Unknown Source)
at test.ServiceTest.historyTest(ServiceTest.java:64)
at test.ServiceTest.main(ServiceTest.java:100)
Caused by: java.lang.ClassCastException: com.ibm.xml.xlxp2.jaxb.JAXBContextImpl incompatible with com.sun.xml.internal.bind.api.JAXBRIContext
at java.lang.ClassCastException.<init>(ClassCastException.java:58)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.<clinit>(SOAPFaultBuilder.java:545)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:205)
... 6 more
Test Class:
package test;
import be.ipc.css.ws.GcssWebServiceService;
import be.ipc.css.ws.IGcssWebService;
import be.ipc.css.ws.InvalidItemIdStructureFault_Exception;
import be.ipc.css.ws.ProductNotAllowedFault_Exception;
import be.ipc.css.ws.common.Product;
import be.ipc.css.ws.history.GetHistoryInput;
import be.ipc.css.ws.history_output.GetHistoryOutput;
import be.ipc.css.ws.history_output.HistoryItem;
import be.ipc.css.ws.history_output.Type;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.handler.Handler;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* <strong>Project: TODO: project name</strong><br/>
* <b>Url:</b> TODO: url<br/>
* <b>Date:</b> 15.05.14<br/>
* <b>Time:</b> 23:42 <br/>
* Copyright(C) 2014 IT Service Plus <br/>
* <b>Description:</b><br/>
* TODO: description
*/
public class ServiceTest {
private static Service webService;
private static IGcssWebService servicePort;
public void initService() throws MalformedURLException {
URL url = new URL("http://cs-demo.ipc.be/CSS_UA2/services/gcssWebService/1.0");
QName qname = new QName("http://ws.css.ipc.be/", "GcssWebServiceService");
/*java.util.Properties props = System.getProperties();
props.setProperty("http.proxyHost", "proxy.test.com");
props.setProperty("http.proxyPort", "8080");*/
webService = GcssWebServiceService.create(url, qname);
servicePort = webService.getPort(IGcssWebService.class);
try {
CustomSoapHandler sh = new CustomSoapHandler("user_us", "*******");
List<Handler> new_handlerChain = new ArrayList<Handler>();
new_handlerChain.add(sh);
((BindingProvider)servicePort).getBinding().setHandlerChain(new_handlerChain);
} catch (Throwable e) {
e.printStackTrace();
}
//((BindingProvider)servicePort).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "user_us");
//((BindingProvider)servicePort).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "*******");
}
public void historyTest() throws ProductNotAllowedFault_Exception, InvalidItemIdStructureFault_Exception {
GetHistoryInput input = new GetHistoryInput();
input.setItemId("CC027607063NL");
input.setProduct(Product.EPG);
System.out.println("Check method call");
GetHistoryOutput output = servicePort.getHistory(input);
System.out.println("Check result");
//Assert.assertNotNull(output);
//Assert.assertNotNull(output.getHistory());
//Assert.assertNotNull(output.getHistory().getHistoryItem());
System.out.println("Received: " + output.getHistory().getHistoryItem().size() + "elements:");
System.out.println("-----------------------");
for(int i=0;i<output.getHistory().getHistoryItem().size();i++) {
HistoryItem it = output.getHistory().getHistoryItem().get(i);
System.out.println("#" + i + ": id=" + it.getId() + ", type=" + it.getType().value());
}
System.out.println("Check 3 history items");
//Assert.assertEquals(3, output.getHistory().getHistoryItem().size());
HistoryItem it1 = output.getHistory().getHistoryItem().get(0);
HistoryItem it2 = output.getHistory().getHistoryItem().get(1);
HistoryItem it3 = output.getHistory().getHistoryItem().get(2);
/*Assert.assertEquals(Type.QUMQ, it1.getType());
Assert.assertEquals(161L, it1.getId());
Assert.assertEquals(Type.SUM, it2.getType());
Assert.assertEquals(652L, it2.getId());
Assert.assertEquals(Type.L_1_Q, it3.getType());
Assert.assertEquals(13742L, it3.getId());*/
}
public static void main(String[] args) {
ServiceTest test = new ServiceTest();
try {
test.initService();
test.historyTest();
} catch(Exception e ){
e.printStackTrace();
}
}
}
Soap Handler:
package test;
import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.util.Set;
/**
* <strong>Project: TODO: project name</strong><br/>
* <b>Url:</b> TODO: url<br/>
* <b>Date:</b> 16.05.14<br/>
* <b>Time:</b> 0:48 <br/>
* Copyright(C) 2014 IT Service Plus <br/>
* <b>Description:</b><br/>
* TODO: description
*/
public class CustomSoapHandler implements SOAPHandler<SOAPMessageContext> {
private static final String AUTH_PREFIX = "wsse";
private static final String AUTH_NS =
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private String username;
private String password;
public CustomSoapHandler(String username, String password) {
this.username = username;
this.password = password;
}
public boolean handleMessage(SOAPMessageContext context) {
try {
SOAPEnvelope envelope =
context.getMessage().getSOAPPart().getEnvelope();
SOAPFactory soapFactory = SOAPFactory.newInstance();
SOAPElement wsSecHeaderElm =
soapFactory.createElement("Security", AUTH_PREFIX, AUTH_NS);
Name wsSecHdrMustUnderstandAttr =
soapFactory.createName("mustUnderstand", "S",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
wsSecHeaderElm.addAttribute(wsSecHdrMustUnderstandAttr, "1");
SOAPElement userNameTokenElm =
soapFactory.createElement("UsernameToken", AUTH_PREFIX,
AUTH_NS);
Name userNameTokenIdName =
soapFactory.createName("id", "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
userNameTokenElm.addAttribute(userNameTokenIdName,
"UsernameToken-ORbTEPzNsEMDfzrI9sscVA22");
SOAPElement userNameElm =
soapFactory.createElement("Username", AUTH_PREFIX, AUTH_NS);
userNameElm.addTextNode(username);
SOAPElement passwdElm =
soapFactory.createElement("Password", AUTH_PREFIX, AUTH_NS);
Name passwdTypeAttr = soapFactory.createName("Type");
passwdElm.addAttribute(passwdTypeAttr,
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
passwdElm.addTextNode(password);
userNameTokenElm.addChildElement(userNameElm);
userNameTokenElm.addChildElement(passwdElm);
wsSecHeaderElm.addChildElement(userNameTokenElm);
if (envelope.getHeader() == null) {
SOAPHeader sh = envelope.addHeader();
sh.addChildElement(wsSecHeaderElm);
} else {
SOAPHeader sh = envelope.getHeader();
sh.addChildElement(wsSecHeaderElm);
}
} catch (Throwable e) {
e.printStackTrace();
}
return true;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
#Override
public void close(MessageContext context) {
//To change body of implemented methods use File | Settings | File Templates.
}
#Override
public Set<QName> getHeaders() {
return null;
}
}
The main reason for your error is incompatible JAXB implementation classes:
aused by: java.lang.ClassCastException: com.ibm.xml.xlxp2.jaxb.JAXBContextImpl incompatible with com.sun.xml.internal.bind.api.JAXBRIContext
Probably the best way to fix this is packaging your own version of JAXB within your application(inside the lib folder) and than change the class loader from WebSphere to be Parent Last.
After that, restart and try it again. If still doesn't work you can try adding your JAXB implementation libraries directly to the Application Server classloader. You can do that creating a directory under $WEBSPHERE_HOME/AppServer/classes and placing your JAXB implementation classes there. Be aware that this approach adds the dropped jars to all WebSphere instances running using this binary codebase.
You can learn more about WebSphere classloaders.
Hope this helps.

Adding username and password to soap header in Java by using PasswordText Type and axis2

I want to add username and password to soap header in java by using PasswordText Type and axis2.
Code snippet I use
public static void WSSPasswordAuthentication(org.apache.axis2.client.ServiceClient client, String endPointUrl, String username, String password) throws CSException{
OMFactory omFactory = OMAbstractFactory.getOMFactory();
OMElement omSecurityElement = omFactory.createOMElement(new QName( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse"), null);
OMElement omusertoken = omFactory.createOMElement(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "UsernameToken","wsse"), null);
OMElement omuserName = omFactory.createOMElement(new QName("", "Username", "wsse"), null);
omuserName.setText(username);
OMElement omPassword = omFactory.createOMElement(new QName("", "Password", "wsse"), null);
omPassword.addAttribute("Type","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText",null );
omPassword.setText(password);
omusertoken.addChild(omuserName);
omusertoken.addChild(omPassword);
omSecurityElement.addChild(omusertoken);
client.addHeader(omSecurityElement);
}
And resultant header :
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsu:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><Username>erapor</Username><Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">erapor</Password></wsu:UsernameToken></wsse:Security>
But
The header I want : <soapenv:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><wsse:Username>erapor</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">erapor</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header>
Otherwise I couldn't use the header
How can I modify?
You can use plain JAXWS if you have an option to resolve this instead of using AXIS2 on the client side. This is generic and easy to add these kind of security headers.
In your JDK 6.0 HOME (This example works only from JDK 6.0 and above)
jdk1.6.0_26\bin\wsimport is an utility available
You can create the stub using the wsimport utility
wsimport -keep -verbose http://localhost:8080/<WebserviceName>/services/<WebserviceName>?wsdl
Create a message handler
MessageHandler.java
package com.secure.client;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class MessageHandler implements SOAPHandler<SOAPMessageContext>{
#Override
public void close(MessageContext arg0) {
// TODO Auto-generated method stub
}
#Override
public Set getHeaders() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean handleMessage(SOAPMessageContext soapMessageContext) {
try {
boolean outMessageIndicator = (Boolean) soapMessageContext
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outMessageIndicator) {
SOAPEnvelope envelope = soapMessageContext.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
username.addTextNode("wsuser");
SOAPElement password = usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode("wspwd");
}
} catch (Exception ex) {
throw new WebServiceException(ex);
}
return true;
}
}
Create HeaderHandlerResolver.java
package com.secure.client;
import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;
public class HeaderHandlerResolver implements HandlerResolver {
#SuppressWarnings("unchecked")
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
MessageHandler hh = new MessageHandler();
handlerChain.add(hh);
return handlerChain;
}
}
You can create the client code using stub
Client.java
import javax.xml.ws.BindingProvider;
import com.secure.HelloService;
import com.secure.HelloServiceException;
import com.secure.HelloServicePortType;
public class Client {
public static void main(String[] args) {
HelloService service = new HelloService();
service.setHandlerResolver(new HeaderHandlerResolver());
HelloServicePortType port = service.getHelloServiceHttpSoap11Endpoint();
// Use the BindingProvider's context to set the endpoint
BindingProvider bp = (BindingProvider)port;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/<WebserviceName>/services/<WebserviceName>");
System.out.println(port.getVersion());
try {
System.out.println(port.getHello("Zack"));
} catch (HelloServiceException e) {
e.printStackTrace();
}
}
}