Application Authentication with JAX-WS

One of the common way to handle authentication in JAX-WS is client provides “username” and “password”, attached it in SOAP request header and send to server, server parse the SOAP document and retrieve the provided “username” and “password” from request header and do validation from database, or whatever method prefer.

In this article, we show you how to implement the above “application level authentication in JAX-WS“.

Ideas…

On the web service client site, just put your “username” and “password” into request header.

    Map<String, Object> req_ctx = ((BindingProvider)port).getRequestContext();
    req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WS_URL);
 
    Map<String, List<String>> headers = new HashMap<String, List<String>>();
    headers.put("Username", Collections.singletonList("mkyong"));
    headers.put("Password", Collections.singletonList("password"));
    req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);

On the web service server site, get the request header parameters via WebServiceContext.

    @Resource
    WebServiceContext wsctx;
 
    @Override
    public String method() {
 
        MessageContext mctx = wsctx.getMessageContext();
 
	//get detail from request headers
        Map http_headers = (Map) mctx.get(MessageContext.HTTP_REQUEST_HEADERS);
        List userList = (List) http_headers.get("Username");
        List passList = (List) http_headers.get("Password");
 
    //...

That’s all, now, your deployed JAX-WS is supported application level authentication.

Authentication with JAX-WS Example

See a complete example.

1. WebService Server

Create a simple JAX-WS hello world example to handle the authentication in application level.

File : HelloWorld.java

package com.mkyong.ws;
 
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();
 
}

HelloWorldImpl.java

package com.mkyong.ws;
 
import java.util.List;
import java.util.Map;
 
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
 
//Service Implementation Bean
@WebService(endpointInterface = "com.mkyong.ws.HelloWorld")
public class HelloWorldImpl implements HelloWorld{
 
    @Resource
    WebServiceContext wsctx;
 
    @Override
    public String getHelloWorldAsString() {
 
	MessageContext mctx = wsctx.getMessageContext();
 
	//get detail from request headers
        Map http_headers = (Map) mctx.get(MessageContext.HTTP_REQUEST_HEADERS);
        List userList = (List) http_headers.get("Username");
        List passList = (List) http_headers.get("Password");
 
        String username = "";
        String password = "";
 
        if(userList!=null){
        	//get username
        	username = userList.get(0).toString();
        }
 
        if(passList!=null){
        	//get password
        	password = passList.get(0).toString();
        }
 
        //Should validate username and password with database
        if (username.equals("mkyong") && password.equals("password")){
        	return "Hello World JAX-WS - Valid User!";
        }else{
        	return "Unknown User!";
        }
 
    }	
}

2. EndPoint Publisher

Create an endpoint publisher to deploy above web service at this URL : “http://localhost:9999/ws/hello

File : HelloWorldPublisher.java

package com.mkyong.endpoint;
 
import javax.xml.ws.Endpoint;
import com.mkyong.ws.HelloWorldImpl;
 
//Endpoint publisher
public class HelloWorldPublisher{
 
    public static void main(String[] args) {
	   Endpoint.publish("http://localhost:9999/ws/hello", new HelloWorldImpl());
    }
 
}

3. WebService Client

Create a web service client to send “username” and “password” for authentication.

File : HelloWorldClient.java

package com.mkyong.client;
 
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.handler.MessageContext;
 
import com.mkyong.ws.HelloWorld;
 
public class HelloWorldClient{
 
	private static final String WS_URL = "http://localhost:9999/ws/hello?wsdl";
 
	public static void main(String[] args) throws Exception {
 
	URL url = new URL(WS_URL);
        QName qname = new QName("http://ws.mkyong.com/", "HelloWorldImplService");
 
        Service service = Service.create(url, qname);
        HelloWorld hello = service.getPort(HelloWorld.class);
 
        /*******************UserName & Password ******************************/
        Map<String, Object> req_ctx = ((BindingProvider)hello).getRequestContext();
        req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WS_URL);
 
        Map<String, List<String>> headers = new HashMap<String, List<String>>();
        headers.put("Username", Collections.singletonList("mkyong"));
        headers.put("Password", Collections.singletonList("password"));
        req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
        /**********************************************************************/
 
        System.out.println(hello.getHelloWorldAsString());
 
    }
}

Output

Hello World JAX-WS - Valid User!

4. Tracing SOAP Traffic

From top to bottom, showing how SOAP envelope flows between client and server.

1. Client send request, the username “mkyong” and password “password” are included in the SOAP envelope.

POST /ws/hello?wsdl HTTP/1.1
Password: password
Username: mkyong
SOAPAction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Type: text/xml; charset=utf-8
User-Agent: Java/1.6.0_13
Host: localhost:8888
Connection: keep-alive
Content-Length: 178
 
<?xml version="1.0" ?>
	<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
		<S:Body>
			<ns2:getHelloWorldAsString xmlns:ns2="http://ws.mkyong.com/"/>
		</S:Body>
	</S:Envelope>

2. Server send back a normal response.

HTTP/1.1 200 OK
Transfer-encoding: chunked
Content-type: text/xml; charset=utf-8
 
<?xml version="1.0" ?>
	<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
		<S:Body>
			<ns2:getHelloWorldAsStringResponse xmlns:ns2="http://ws.mkyong.com/">
				<return>Hello World JAX-WS - Valid User!</return>
			</ns2:getHelloWorldAsStringResponse>
		</S:Body>
	</S:Envelope>

Done.

Download Source Code

Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

  • Pingback: watch movies online()

  • Pingback: watch movies online()

  • Pingback: watch movies online()

  • Pingback: Blue Coaster33()

  • Pingback: Web Service Authentication using Java | I'm IT Professional Service (Architect, Designer, Developer, Analyst & Business Consultant, on SOA, SCM, SCO, ERP & CRM()

  • Dinesh Pise

    I have getting below error when depoyed in Jboss 5.1 GA but works fine in Jboss 4.2

    java.lang.LinkageError: loader constraint violation in interface itable initialization: when resolving method “com.sun.xml.ws.util.xml.XMLStreamReaderFilter.getAttributeName(I)Ljavax/xml/namespace/QName;” the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the current class, com/sun/xml/ws/util/xml/XMLStreamReaderFilter, and the class loader (instance of ) for interface javax/xml/stream/XMLStreamReader have different Class objects for the type javax/xml/namespace/QName used in the signature

  • rakesh

    Hi All ,
    I am following the above given program.
    It’s working with jdk 1.6 with this commands
    1. wsgen -keep -cp bin/ -s src/ com.mkyong.ws.HelloWorldImpl(Publishing the Survice)
    2.wsimport -keep -s ./src -p com.mkyong.client http://localhost:8080/ws/hello?wsdl(Creating the respective Service file for client)

    It.s always taking in Service implementation file username =”” and password=””
    Therefore always it saying unknown user while i am passing username =”mkyong” and password=”password”

    Can anyone help me how i can get the right input from the client file?
    Thanks and regards,
    Rakesh

  • Sudhakar

    Simply Superb. This saved me so much of time !

  • Marcos Daniel Petry

    Thank you Mkyong. Your tutorials are very usefull for us.
    Hugs!

  • dkbose

    First of all, I’m a huge fan of your articles.. Simple, yet so effective..

    However, I’ve followed this tutorial and not achieved the expected results. I am using Spring 3.0.3 and on invocation of the method, WebServiceContext is null. It isn’t being injected.

    Any help on how to inject WebServiceContext would be appreciated. Thanks in advance..

  • Muzimil Basha

    Thanks for tutorial. I am trying to implement this for my web service method. I had successfully added it in my service. I am using Apache Axis2 for generating the client. It will create all the required classes. Currently I am using

     HelloWorldImplServiceStub stub = new HelloWorldImplServiceStub();
    GetHelloWorldAsString get= new GetHelloWorldAsString();
     
    GetHelloWorldAsStringResponse res= stub.getHelloWorldAsString(get);
    System.out.println(res.get_return());

    Can you tell me how to add headers for this. your suggestion would help me alot.

  • http://tarilabs.wordpress.com/ Tari aka Manga

    Ciao, great example thanks!

    Actually FYI I found maybe simpler to put username/password via BindingProvider if it’s not a requirement to put them manually in the HTTP headers, e.g.:

    req_ctx.put(BindingProvider.USERNAME_PROPERTY, "username");
    req_ctx.put(BindingProvider.PASSWORD_PROPERTY, "password");
    

    Hope in having provided a good suggestion as well ;)
    ps: very great tutorials all over your site, good job!! Very helpful!!!
    Ciao,

  • Sonu Thomas

    Note : error in source code

    In source code provided to download, Webservice is published in port 9999 and client is accessing at 8888.So error is coming. Kindly change it accordingly..

  • Azahrudhin

    Hi Mkyong,
    Thank you for all your posts , they are simple and easy to understand.

    Could you please post and example for writing client using certificate i.e consuming a webservice which will use certificate to authenticate

    01. I have generated the client bindings using NetBeans which intern uses wsimport of JAX-WS RI 2.2.

    02. How to write the client program to access the webservice using cert files.

    01. I have successfully generated the client bindings.
    I need to configure the Keysotre and TrustStore.

    03. Please help to configure the trustsotre and keystore in the client programs.

  • http://no.com deepak

    i have no website.
    listen dear as you have mention an example i am not able to run your example ,error is coming
    Exception in thread “main” javax.xml.ws.WebServiceException: java.net.ConnectException: Connection refused: connect.

    please share me the reason.

  • http://chesstechnology.com José Gamboas

    Hi,
    Thanks for this tutorial, I need implement this example for learning jax-ws.

    how I can make a header for connect soapUI and php?
    I used This but no work:
    Request:

    mkyong
    password

    Response:

    Unknown User!{accept-encoding=[gzip,deflate], content-length=[340], content-type=[text/xml;charset=UTF-8], host=[localhost:8080], soapaction=[“”], user-agent=[Jakarta Commons-HttpClient/3.1]}

    Thanks for help me….

  • Jairaj Chetty

    Great tutorial thanks. Any idea how to replicate the client request using soapUI?

  • Jairaj Chetty

    Great tutorial, thanks. Just what I needed. Any idea how to send requests from soapUI with username/password?

  • Pingback: Basic Authentication with SOAP Web Service « dwuysan()

  • manish gupta

    hi mkyong,

    Thanks, its valuable example!!

  • Enduro

    I guess this method does not seem to be safe for replay-attacks.

    I would recommend to use UsernameToken.

    • http://www.mkyong.com mkyong

      This article is showing the basic about how to perform authentication in jax-ws. For advance security feature, just enhance it to suit your needs.

      I’m interest at your UsernameToken example, mind to share it? Thanks.

      • Ariel Snir

        Hi dear MyKong,
        You are a great man that help a lot in promoting technology
        worldwide by sharing knowledge.
        So , thanks you very much.

        I have a request,
        Can you kindly, share an example with UsernameToken for performing authentication in jax-ws.

        Best regards,
        Ariel.

  • Pingback: JAX-WS, Authentication and Authorization – How to?()

  • Pingback: JAX-WS, Authentication and Authorization – How to? | Gravity Layouts()

  • Bharat

    Hi,

    in your example when i read the following code

    Map httpHeaders = (Map) mctx.get(MessageContext.HTTP_REQUEST_HEADERS);
    The values in httpHeaders are coming as following:
    {jboss-remoting-version=[22], connection=[keep-alive], host=[usbur043060:30080], user-agent=[JBossRemoting - 2.2.2.SP7 (Bluto)], transfer-encoding=[chunked], content-type=[text/xml; charset=UTF-8], accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], soapaction=[""]}
    
    List userList = (List) httpHeaders.get("Username");
    List passList = (List) httpHeaders.get("Password");

    but i never get any value in userList and passList. they are always null.

    Please guide me.

  • Floris

    Is the username/password send in plaintent in the resulting SOAP messages? If so I would suggest combining the authentication with some form of confidentiality(e.g. using TLS).

    • http://www.mkyong.com mkyong

      ya, in production, SSL is always recommended.

      • Ashish

        Hi,
        This is a vary good example.Thanks a ton for guiding us.
        Can yoiu please also tell us who to implement SSL in client side(encryption) and server side(decryption) using above mentioned code.

        Thanks in advance,
        Ashish

  • Pingback: JAX-WS Tutorial()

  • PeterR

    Hello,

    I have found on mkyong.com everything needed for my project Liferay Spring jax-ws .

    Thank you very much!

    • http://www.mkyong.com mkyong

      Hi Peter, good to know that my articles did help someone :)

      • RajeshR

        Hi
        ON WAS 7.0 I am runnig the application that calls the webservice.
        In the client side code of webservice, I have tried to set the headers, but its giving me exception at the very first line of the code

        Map req_ctx = ((BindingProvider)port).getRequestContext();

        excpetion is
        [7/27/12 12:11:47:075 IST] 00000017 SystemErr R javax.ejb.EJBException: EBS Error code[810666] uk.co.respond.www.NwsInterfaceSoapBindingStub incompatible with javax.xml.ws.BindingProvider

        I am struggling a lot since a month with this issue. Could you please help.

        My Code:
        ————————-
        if (nwsInterfaceSoapPort == null)
        _initNwsInterfaceSoapPortProxy();
        System.out.println(“>>NwsInterfaceSoapPortProxy.add_Complaint():Start addding Header<<<");
        Map reqContext = ((BindingProvider)nwsInterfaceSoapPort).getRequestContext();
        }

        ————————————————————–

        public class NwsInterfaceSoapPortProxy implements uk.co.respond.www.NwsInterfaceSoapPort {
        private boolean _useJNDI = true;
        private String _endpoint = null;
        private uk.co.respond.www.NwsInterfaceSoapPort nwsInterfaceSoapPort = null;

        public NwsInterfaceSoapPortProxy() {
        _initNwsInterfaceSoapPortProxy();
        }

        private void _initNwsInterfaceSoapPortProxy() {

        if (_useJNDI) {
        try{
        javax.naming.InitialContext ctx = new javax.naming.InitialContext();
        nwsInterfaceSoapPort = ((uk.co.respond.www.NetPointWebService)ctx.lookup("java:comp/env/service/NetPointWebService")).getNwsInterfaceSoapPort();
        }
        catch (javax.naming.NamingException namingException) {}
        catch (javax.xml.rpc.ServiceException serviceException) {}
        }
        if (nwsInterfaceSoapPort == null) {
        try{
        nwsInterfaceSoapPort = (new uk.co.respond.www.NetPointWebServiceLocator()).getNwsInterfaceSoapPort();
        }
        catch (javax.xml.rpc.ServiceException serviceException) {}
        }
        if (nwsInterfaceSoapPort != null) {
        if (_endpoint != null)
        ((javax.xml.rpc.Stub)nwsInterfaceSoapPort)._setProperty("javax.xml.rpc.service.endpoint.address", _endpoint);
        else
        _endpoint = (String)((javax.xml.rpc.Stub)nwsInterfaceSoapPort)._getProperty("javax.xml.rpc.service.endpoint.address");
        }

        }
        ———————————
        public class NwsInterfaceSoapBindingStub extends com.ibm.ws.webservices.engine.client.Stub implements uk.co.respond.www.NwsInterfaceSoapPort {
        public NwsInterfaceSoapBindingStub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws com.ibm.ws.webservices.engine.WebServicesFault {
        if (service == null) {
        super.service = new com.ibm.ws.webservices.engine.client.Service();
        }
        else {
        super.service = service;
        }
        super.engine = ((com.ibm.ws.webservices.engine.client.Service) super.service).getEngine();
        initTypeMapping();
        super.cachedEndpoint = endpointURL;
        super.connection = ((com.ibm.ws.webservices.engine.client.Service) super.service).getConnection(endpointURL);
        super.messageContexts = new com.ibm.ws.webservices.engine.MessageContext[2];
        }
        ..}
        ———————————-
        public class NetPointWebServiceLocator extends com.ibm.ws.webservices.engine.client.Service implements uk.co.respond.www.NetPointWebService {

        public uk.co.respond.www.NwsInterfaceSoapPort getNwsInterfaceSoapPort() throws javax.xml.rpc.ServiceException {
        java.net.URL endpoint;
        try {
        endpoint = new java.net.URL(nwsInterfaceSoapPort_address);
        }
        catch (java.net.MalformedURLException e) {
        return null; // unlikely as URL was validated in WSDL2Java
        }
        return getNwsInterfaceSoapPort(endpoint);
        }

        public uk.co.respond.www.NwsInterfaceSoapPort getNwsInterfaceSoapPort(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
        try {
        uk.co.respond.www.NwsInterfaceSoapBindingStub _stub = new uk.co.respond.www.NwsInterfaceSoapBindingStub(portAddress, this);
        _stub.setPortName(getNwsInterfaceSoapPortWSDDPortName());
        return _stub;
        }
        catch (com.ibm.ws.webservices.engine.WebServicesFault e) {
        return null;
        }
        }
        }

  • Remco

    Thanks alot for this excellent tutorial

  • Pingback: Tomcat – Container Authentication with JAX-WS()

  • http://www.geeklisted.com Chris

    Great tutorials, very easy to read and follow. Thanks.