Container Authentication with JAX-WS – (Tomcat version)
In this article, we show you how to implement container authentication with JAX-WS, under Tomcat 6.0. In this way, the authentication is declarative rather than programmatic like this – application authentication in JAX-WS. And Tomcat implement the container authentication via security realm.
At the end of this article, the deployed web service will authenticate user based on the authentication data stored in Tomcat’s conf/tomcat-users.xml file.
1. WebService
Create a simple JAX-WS, RPC style.
File : UserProfile.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 UserProfile{ @WebMethod String getUserName(); }
File : UserProfileImpl.java
package com.mkyong.ws; import javax.jws.WebService; //Service Implementation Bean @WebService(endpointInterface = "com.mkyong.ws.UserProfile") public class UserProfileImpl implements UserProfile{ @Override public String getUserName() { return "getUserName() : returned value"; } }
2. web.xml
Configure a security role “operator”, make url “/user” required basic http authentication. See below web.xml file, self-explanatory.
File : web.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> //... <security-role> <description>Normal operator user</description> <role-name>operator</role-name> </security-role> <security-constraint> <web-resource-collection> <web-resource-name>Operator Roles Security</web-resource-name> <url-pattern>/user</url-pattern> </web-resource-collection> <auth-constraint> <role-name>operator</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> </login-config> <servlet-mapping> <servlet-name>user</servlet-name> <url-pattern>/user</url-pattern> </servlet-mapping> //... </web-app>
In production, it’s recommended to set the transport guarantee to “CONFIDENTIAL“, so that any access to resources via normal http request, such as http://localhost:8080/ws/user, Tomcat will redirect the request to https request https://localhost:8443/ws/user. Of course, the redirect https can be configure in The Tomcat’s
conf/server.xml.<user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint>
See this article – Make Tomcat to support SSL or https connection
3. Tomcat Users
Add new role, username and password in $Tomcat/conf/tomcat-users.xml file. In this case, add new user “mkyong”,”123456″ and attached it to a role named “operator”.
File : $Tomcat/conf/tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="tomcat"/> <role rolename="operator"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="mkyong" password="123456" roles="operator"/> <user name="admin" password="admin" roles="admin,manager" /> </tomcat-users>
4. Tomcat Realm
Configure security realm in $Tomcat/conf/server.xml file. In this case, uses default UserDatabaseRealm to read the authentication information in $Tomcat/conf/tomcat-users.xml.
File : $Tomcat/conf/server.xml
<GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
5. Deploy JAX-WS web service on Tomcat
See this detail guide on how to deploy JAX-WS web services on Tomcat.
6. Testing
Now, any access to your deployed web service is required username and password authentication, see figure :
URL : http://localhost:8080/WebServiceExample/user

7. WebService Client
To access the deployed web service, bind a correct username and password like this :
UserProfile port = service.getPort(UserProfile.class); BindingProvider bp = (BindingProvider) port; bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "mkyong"); bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "123456");
File : WsClient.java
package com.mkyong.client; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.BindingProvider; import javax.xml.ws.Service; import com.mkyong.ws.UserProfile; public class WsClient{ //can't parse wsdl "http://localhost:8080/WebServiceExample/user.wsdl" directly //save it as local file, and parse it private static final String WS_URL = "file:c://user.wsdl"; public static void main(String[] args) throws Exception { URL url = new URL(WS_URL); QName qname = new QName("http://ws.mkyong.com/", "UserProfileImplService"); Service service = Service.create(url, qname); UserProfile port = service.getPort(UserProfile.class); //add username and password for container authentication BindingProvider bp = (BindingProvider) port; bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "mkyong"); bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "123456"); System.out.println(port.getUserName()); } }
output
getUserName() : returned value
For those clients provided an invalid username or password, Tomcat will return following exception :
Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: request requires HTTP authentication: Unauthorized
Done.
Download Source Code
Reference
- Tomcat realm HOW TO
- Example: Basic Authentication with JAX-WS
- SSL and HTTP BASIC authentication with Glassfish and JAX-WS

hello mkyong….I create a web service using tomcat and axis2 in windows using eclipse
and when I update the web.xml as u mentioned above….even the tomcat-user.xml from program file.
I didnt made any change in service.xml
but when I run the service it does not accept my user name and password..directly from authentication required window…
Is is possible to access from there…or need to make a client….?
Hi,
I am not sure why in my case following code is not working.
So I googled a bit and added these lines
Any reason ? Is I am missing something here why original code was giving HTTP ERROR 401 to me.I know its related to authentication.But why ?
Is there are any side effects of using Authenticator ?
Kind Regards,
Vijayendra Bhati
Hi MKyong
I think I have been succesfully been able to deploy your example to tomcat. But when I try to run WsClient.java as a java application it says that it cannot access that it cannot access http://localhost:8080/WebServicesExample/user?wsdl and I understand why that is because I do have a user.wsdl file defined on my hard-drive.
Even when I try to access the WSDL file from http://localhost:8080/WebServicesExample/user it gives me a 404 Not Found type of error message. So am I expected to create my own WSDL file for this or get the WSDL file from somewhere else ? Was that how this example was intended to be or am I missing a trick somewhere ?
Any clarification here would greatly help me.
Thanks
I can see which you are putting a a lot of efforts into your blog. Preserve posting the good perform.Some really helpful information in there. Bookmarked. Wonderful to see your website. Thanks!
Just a thought:
Is there anyway to persuade tomcat to give out the wsdl, without requiring a userid/password?
Yes, I know its a far shot, since the authentication is bound to the service that must be protected. But maybe someone comes up with a solution anyway.
KR
Henrik
By default, and you didn’t configure Tomcat authentication like what mention in above article, users can get wsdl directly.
Am I the only one who thinks that getting the wsdl from a local file is pretty awful?
I if you deploy your client in a jar, you will need to put the wsdl somewhere in your filesystem, and if the wsdl changes, you are up the creek without a paddle.
But it seems that with jax-ws/Basic authentication this is the only option.
Anyone with a solution to this will get my personal commendation with oak leaves, eagles and diamonds!
Kind regards
Henrik
Hi, I were implementing your tutorial and it worked fine with one WS, however, when I wanted to assign to a user more than one WS I got troubles…I mean, for example, I have 4 WS and I want to grant permissions over 2 specified WS to 2 different users, when the user access to one of its suppossed assigned WS it works fine, but after the user can access the other WS. I don´t know if there is a concrete way to organize de web.xml. Thx for your attention. Hope your answer. =D