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.
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.
You say “… attached it in SOAP request header …”. But in this article You explain HTTP request header of SOAP request. I think it is important to differ between HTTP header and SOAP header. Both are possible, but this are very different ways.
To Test with SOAP UI
Add Authentication headers in SOAP UI
http://www.soapui.org/SOAP-and-WSDL/adding-headers-and-attachments.html
username – mkyoung
password – password
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..
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.:
Hope in having provided a good suggestion as well 😉
ps: very great tutorials all over your site, good job!! Very helpful!!!
Ciao,
Hi Mkyong,
Is there any way to close this web service connection?
Thats helped me to set the content-type. thank you.
This can also be used
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
“UserName”,
“Password1#”.toCharArray());
}
});
Hi Mkyong,
Above soap web service working fine with soap request and its content type as text/xml. Please help me to write soap web service with content type of soap request as application/xml. Above web service not working with content type of soap request as application/xml.
SEVERE: Unsupported Content-Type: application/xml Supported ones are: [text/xml].
Please write a program of soap web service that will take content type of soap request as application/xml.
I know SOAP can be used in a lot of protocols. The most used is HTTP, but there are a lot of options. if I use the authentication by means of header. I would be restricting the SOAP message only for HTTP Protocolo. For solving the problem and of this way has interoperability, you should use ‘WSIT’. Do you have some example of this way?
WebServiceContext bean is null for me . Can you suggest what library needs to be included?
Hey Rita,
I am getting the same error and none of the solution that I found on stack overflow works for me. Could you please let me know how you resolved this.
Thanks,
Deepak
@Resource
private WebServiceContext wsctx;
Make this variable on the top of ServiceImpl Class
WebServiceContext bean is null for me . Can you suggest what library needs to be included?
Hey,
Anyone can help me deploy this HelloWorld web service to weblogic? (Instead of make it available by the publisher.)
I would like to test it via SOAP UI.
Keep on the good work,
Cheers,
HL
Hi,
could you please upload signature authentication post?
Thanks,
Gahininath
Great post but while testing with above code getting failed to connect the wsdl file.please help on urgent basis
hi Mkyoung, please help me: how to get WSS passwordType (passwordText or passwordDigest) from headers?
Hi,
can you give some example for Digest authentication in java client ?
Great post save a day
Hi All Develpoer this is greate example and running example but i did’nt find
QName qname = new QName(“http://ws.mkyong.com/”, “HelloWorldImplService”);
means HelloWorldImplService class code if i put our URI name this is not run so i want some changes in HelloWorldImplService. so please reply as soon as possible
i dont know how to run this example.
it is eclipse project or netbeans project?
please help me run this simple example.
thank you.
Hi,
Great post and it helped. However, I am trying to make a Spring client and authorize it using Spring. How can I do that?
Sir,How to create an Android client for this secured jax-ws?Please help
Hello,
I implemented a small weservice with. net, I need to invoke the webservice from java, I followed the instructions in this post, but when I do I debug the webservice the username and password are blank. Why?
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
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
Simply Superb. This saved me so much of time !
Thank you Mkyong. Your tutorials are very usefull for us.
Hugs!
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
Can you tell me how to add headers for this. your suggestion would help me alot.
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..
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.