Skip to main content

Securing A JAVA-SE 6 WebService


Last Update : 01 November 2007


JAVA SE 6 provides support for developing WebServices.  More details about this can be obtained from : http://java.sun.com/developer/technicalArticles/J2SE/jax_ws_2/

How Do We Secure JAVA SE6 WebService(s) ?.

In this article we will explore the different ways in which one can secure a JAVA SE 6 WebService using SOAP Message Security  (Web Services Security).

1. Make use of  WSIT/Metro . (https://wsit.dev.java.net)
2. The second option that comes to mind is  to make use of  XWSS 2.0 style configuration  approach.
3. The third option is to make use of  JAXWS Handlers and the XWSS2.0/3.0  Programmatic API's to achieve security.

There were issues earlier which were preventing approach 1 and 2  from being used (See : https://xwss.dev.java.net/issues/show_bug.cgi?id=16).  We have now fixed the issues and users can make use of  Option 1 and 2.   The most preferred option should be  option 1 since WSIT is Sun's next generation  WebServices Interoperability  Technology and the WS-Security Implementation in WSIT makes use of a Streaming Implemenation for Improved Performance.  Use of  WSIT also implies that the application can make use of  all the other WS-* specifications in a composable manner.

There are 3 complete downloadbale samples with README  that demonstrate the 3 options.

1.  Secure  JDK6 Endpoint and Client  using WSIT Style Security (Download Sample Here)
2.  Secure  JDK6 Endpoint and Client using  XWSS 2.0 Style Security Configuration (Download Sample Here : SecureXWSS20JDK6.zip)
3.  Secure  JDK6 Endpoint  and Client using  JAXWS  Handler's and XWSS 2.0 API's  (Download Sample Here:SecureJDK6WSWithHandlers.zip )

Option 1 mentioned above is to use WSIT (Sun's next generation WebServices Interoperability Technology offering) and the next section explains how one can develop a Secure JDK6 Endpoint and Client.

Developing JDK6 Endpoint and Client  using WSIT Style Security

Currently there is no NetBeans support for developing and securing a JDK6 Style Endpoint. So while use of WSIT for Securing WebServices remains the most preferred option how does one go about developing the WebService and the Client.

The following two blogs show how a JDK6 Endpoint can read the WSIT Configuration from a META-INF directory in the classpath.

http://blogs.sun.com/ritzmann/entry/wsit_with_a_j2se_endpoint
http://blogs.sun.com/arungupta/entry/tango_on_javase_6

So, The easiest way out is to develop a  Secure  JAXWS WebService using NetBeans to run on   GlassFish  and then just make use of the required  files to convert the WebService and Client into a JDK6 Endpoint and a Standalone J2SE Client respectively.

So here are the abstract steps that one may follow.

Developing the JDK6 Endpoint

1.  Develop a Secure JAXWS WebService using  Netbeans (loaded with WSIT Plugin). 
2.  Create a directory for the JDK6 Endpoint sample and create a directory named "server"  under it.  Also create a directory META-INF under the server directory.
3.   Copy from the NetBeans Project  the wsit-*.xml (WSIT Configuration) file located under   build/web/WEB-INF directory  into the META-INF directory created in step 2 abo ve.
4.   Download Sample Keystore and Truststore for the Server from the following  location
  and place them inside the META-INF directory again.  Modify the Keystore and Truststore location attribute in the wsit-*.xml file to point to the downloaded keystore and truststore.  Only the name's of the stores need be specified not the complete path to them.
5.  Incase the Security Profile the Application requires Username/Password validation then either configure a RealmAuthenticationAdapter as documented in https://xwss.dev.java.net/articles/security_config.html.  Or specify a  CallbackHandler  class that does  Username-Password Valdiation.  The downloadable sample uses the latter approach.
6.  After modifiations mentioned in steps 4 and 5 the relevant assertion's inside the WSIT configuration file (located under META-INF) would look something like this :

                <sc:ValidatorConfiguration wspp:visibility="private">
                   <sc:Validator wspp:visibility="private" name="usernameValidator"  classname="test.PlainTextPasswordValidator"/>
                </sc:ValidatorConfiguration>
                <sc:KeyStore wspp:visibility="private" alias="xws-security-server" storepass="changeit" type="JKS" location="server-keystore.jks"/>
                <sc:TrustStore wspp:visibility="private" storepass="changeit" type="JKS" location="server-truststore.jks"/>

7. Now copy the WebService (POJO) from the NetBeans project under the "server" directory.

8. The seven steps above complete the  Secure JDK6 Endpoint development.  If one does not wish to use NetBeans then the main step which requires a lot of manual effort is the writing of the wsit-*.xml (WSIT Configuration) file for the service. This file contains the WSDL annotated with SecurityPolicies for the Service.  The WSIT Tutorial explains in some detail how to write a WSIT configuration file by hand.
9.   Now use Annotation Processor "apt" followed by javac and java to run your JDK6 Endpoint.  The downloadable sample is built and compiled using the following steps.

----------------------------------------------------------------------------------------------------
 SecureJDK6WSITSample\server>apt -cp .;..\webservices-rt.jar;..\webservices-tools.jar test/*.java
warning: Annotation types without processors: [javax.annotation.Resource]
1 warning
warning: Annotation types without processors: [javax.xml.bind.annotation.XmlRoot
Element, javax.xml.bind.annotation.XmlAccessorType, javax.xml.bind.annotation.Xm
lType, javax.xml.bind.annotation.XmlElement]
1 warning

SecureJDK6WSITSample\server>javac -cp .;..\webservices-rt.jar;..\webservices-tools.jar test/*.java

SecureJDK6WSITSample\server>java -cp .;..\webservices-rt.jar;..\webservices-tools.jar test.SecureWebService
Nov 1, 2007 11:42:25 AM [com.sun.xml.ws.policy.jaxws.PolicyConfigParser]  parse
INFO: WSP1049: Loaded WSIT configuration from file: file:/E:/210307/xwss/www/Sec
ureJDK6WSITSample/server/META-INF/wsit-test.SecureWebService.xml
Secure HelloServer is open for business at http://localhost:8080/SecureWS/Secure
WebServiceService

-----------------------------------------------------------------------------------------------------

Developing the Client for the JDK6 Secure Endpoint

The main challenge when developing a  J2SE client again is the writing of  wsit-client.xml (the client side WSIT Configuration ) file.  And again one can develop the entire client for the  JDK6 Endpoint using  NetBeans.  But here are the steps for those who do not want the client to be a Netbeans style package.

1.  Create a directory "client" as a sibling of  the directory "server" created in the previous section
2.  Copy the wsit-client.xml and *Service.xml (file imported by wsit-client.xml)  from the NetBeans  Client Project into a directory META-INF under the "client" directory.  The  wsit-client.xml is located under build/web/WEB-INF/classes/META-INF if your client developed under NetBeans was a Web Client.  If the client was a standalone J2SE client then the wsit-client.xml would be located under build/classes/META-INF
3.  Download and place the place the sample client side keystore and truststore from the following location :

  and place them under the META-INF directory under the client. Then modify the Keystore and Truststore location attribute in the *Service.xml (client side WSIT configuration imported by wsit-client.xml)  file to point to the downloaded keystore and truststore. Only the name's of the stores need be specified not the complete path to them. The Keystore and Truststore assertions after modification would like something like this :

                <sc:KeyStore wspp:visibility="private" storepass="changeit" type="JKS" location="client-keystore.jks" alias="xws-security-client"/>
                <sc:TrustStore wspp:visibility="private" storepass="changeit" type="JKS" location="client-truststore.jks" peeralias="xws-security-server"/>
                <sc:CallbackHandlerConfiguration wspp:visibility="private">
                    <sc:CallbackHandler default="Alice" name="usernameHandler"/>
                    <sc:CallbackHandler default="ecilA" name="passwordHandler"/>
                </sc:CallbackHandlerConfiguration>


4.  Now run wsimport  followed by javac followed by java to run the client against the service.

------------------------------------------------------------------------------------------
cd  client
SecureJDK6WSITSample\client>wsimport -p client http://localhost:8080/SecureWS/SecureWebServiceService?wsdl
SecureJDK6WSITSample\client>javac -cp .;..\webservices-rt.jar;..\webservices-tools.jar mytest/*.java
SecureJDK6WSITSample\client>java -cp .;..\webservices-rt.jar;..\webservices-tools.jar mytest.SecureClient
Nov 1, 2007 12:18:28 PM [com.sun.xml.ws.policy.jaxws.PolicyConfigParser]  parse
INFO: WSP1049: Loaded WSIT configuration from file: file:/E:/210307/xwss/www/Sec
ureJDK6WSITSample/client/META-INF/wsit-client.xml
 First Operation : Hello WORLD
 Second Operation : BYE ALL....

-----------------------------------------------------------------------------------------

So you can download and run the sample application which shows a Secure JDK6 Endpoint and a J2SE Client using WSIT Style Standard and Interoperable Security Configuration.

Developing a JDK6 Endpoint  and Client using  JAXWS  Handler's and XWSS 2.0 API's

 In the rest of this  article we will demonstrate how option 3 can be used to perform Username Authentication using SOAP Message Security.  Note that  XWSS 3.0  contains a new Streaming implementation which provides much higher Message Security Performance than XWSS 2.0. However the improved performance is only supported when using  WSIT Security (Via WS-SecurityPolicy), when option 1 above is used.

Another issue is that although JAVA SE 6 bundles the SAAJ API and RI, the XWSS 2.0/3.0 implementation has a dependency on a SAAJ RI whose packaging is different from the packaging in JAVA SE 6.  We will be working towards fixing this, but until then running this sample would require explicitly adding  the right versions of  SAAJ RI in the classpath.  The link to the right SAAJ RI jar would be indicated  in this article.

Developing the JAVA SE6 WebService

1. Develop a JAVA SE 6 WebService as usual
2. Add a SecurityHandler as the first Handler for the Service. The Security Handler would make use of the XWSS Programmatic API's to secure the Message and Verify Security in the Message. Note that in this article we make use of the Same SecurityHandler for both client and server with different methods getting invoked for server and client side processing.
3. Create an XWSS 2.0 style SecurityConfiguration  that  requires  the incoming messages to contain a Username/Password
4. Develop a SecurityEnvironmentHandler that can handle PasswordValidation

NOTE: The code in the SecurityHandler and SecurityEnvironmentHandler has been very loosely written to create a quick sample....For a real implementation one will need to refine these two classes.

The WebService Code

package simplejdk6ws;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;

import javax.xml.ws.Binding;
import javax.xml.ws.soap.SOAPBinding;
import java.util.List;
import java.util.LinkedList;
import javax.xml.ws.handler.Handler;
import com.sun.xml.wss.SubjectAccessor;
import javax.xml.ws.WebServiceContext;
import javax.jws.WebService;
import javax.annotation.Resource;


@WebService
public class Main {
   
    @Resource WebServiceContext context;

    /** Creates a new instance of Main */
    public Main() {
       
    }
   
    public String sayHello(String arg) {
        try {
        System.out.println("\nRequester Subject " + SubjectAccessor.getRequesterSubject(context));
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
        System.out.println("Hello!!! " + arg);
        return "Hello!!! " + arg;
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
      
        Endpoint endpoint = Endpoint.create(new Main());
        Binding binding = endpoint.getBinding();     
        List<Handler> handlerChain = new LinkedList<Handler>();
        handlerChain.add(new simplejdk6ws.SecurityHandler("server"));
        binding.setHandlerChain(handlerChain);
        endpoint.publish("http://localhost:8080/WebServiceExample/sayhello");
        
        System.out.println("HelloServer is open for business at http://localhost:8080/WebServiceExample/sayhello");

    }  
}

The SecurityHandler

package simplejdk6ws;

import java.util.Set;
import java.util.HashSet;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
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;
import java.io.FileInputStream;
import com.sun.xml.wss.ProcessingContext;
import com.sun.xml.wss.SubjectAccessor;
import com.sun.xml.wss.XWSSProcessorFactory;
import com.sun.xml.wss.XWSSProcessor;
import com.sun.xml.wss.XWSSecurityException;

public class SecurityHandler implements SOAPHandler<SOAPMessageContext> {
   
    XWSSProcessor sprocessor = null;
    String clientOrServer = null;
    XWSSProcessor cprocessor = null;
    /** Creates a new instance of SecurityHandler */
    public SecurityHandler(String cOrs) {
        FileInputStream serverConfig = null;
        FileInputStream clientConfig = null;
        this.clientOrServer = cOrs;               
        try {
            if ("client".equals(this.clientOrServer)) {
                //read client side security config
                clientConfig = new java.io.FileInputStream(
                        new java.io.File("META-INF/user-pass-authenticate-client.xml"));
                //Create a XWSSProcessFactory.
                XWSSProcessorFactory factory = XWSSProcessorFactory.newInstance();
                cprocessor = factory.createProcessorForSecurityConfiguration(
                        clientConfig, new SecurityEnvironmentHandler("client"));
                clientConfig.close();
            } else {
                //read server side security configuration
                serverConfig = new java.io.FileInputStream(
                        new java.io.File("META-INF/user-pass-authenticate-server.xml"));
                //Create a XWSSProcessFactory.
                XWSSProcessorFactory factory = XWSSProcessorFactory.newInstance();
                sprocessor = factory.createProcessorForSecurityConfiguration(
                        serverConfig, new SecurityEnvironmentHandler("server"));
                serverConfig.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }
   
    public Set<QName> getHeaders() {
         QName securityHeader = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse");
         HashSet<QName> headers = new HashSet<QName>();
         headers.add(securityHeader);
         return headers;
    }

    public boolean handleFault(SOAPMessageContext messageContext) {
        return true;
    }

     public boolean handleMessage(SOAPMessageContext messageContext) {
         if ("client".equals(this.clientOrServer)) {
             secureClient(messageContext);
         } else {
             secureServer(messageContext);
         }
        return true;
    }
    public void close(MessageContext messageContext) {}
   
    private void secureServer(SOAPMessageContext messageContext)
    {
        Boolean outMessageIndicator = (Boolean)       
        messageContext.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        SOAPMessage message = messageContext.getMessage();
       
        if (outMessageIndicator.booleanValue()) {
            System.out.println("\nOutbound SOAP:");
            // do nothing....
            return;
        } else {
            System.out.println("\nInbound SOAP:");
             //verify the secured message.
            try{
                ProcessingContext context =  sprocessor.createProcessingContext(message);
                context.setSOAPMessage(message);
                SOAPMessage verifiedMsg= null;
                verifiedMsg= sprocessor.verifyInboundMessage(context);
                System.out.println("\nRequester Subject " + SubjectAccessor.getRequesterSubject(context));
                messageContext.setMessage(verifiedMsg);
            } catch (XWSSecurityException ex) {
                //create a Message with a Fault in it
                //messageContext.setMessage(createFaultResponse(ex));
                ex.printStackTrace();
                throw new WebServiceException(ex);
            } catch(Exception ex){
                ex.printStackTrace();
                throw new WebServiceException(ex);
            }
        }
    }   

    private SOAPMessage createFaultResponse(XWSSecurityException ex) {
        // TODO: add code here
        return null;
    }
    private void secureClient(SOAPMessageContext messageContext) {
        Boolean outMessageIndicator = (Boolean)       
        messageContext.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        SOAPMessage message = messageContext.getMessage();
        if (outMessageIndicator.booleanValue()) {
            System.out.println("\nOutbound SOAP:");
            ProcessingContext context;
            try {
                context = cprocessor.createProcessingContext(message);
                context.setSOAPMessage(message);
                SOAPMessage secureMsg = cprocessor.secureOutboundMessage(context);
                secureMsg.writeTo(System.out);
                messageContext.setMessage(secureMsg);
            } catch (XWSSecurityException ex) {
                ex.printStackTrace();
                throw new RuntimeException(ex);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
            return;
        } else {
            System.out.println("\nInbound SOAP:");
            //do nothing
            return;
        }     
    }
}

The XWSS 2.0 Style Server Side Configuration

<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true" >
    <xwss:RequireUsernameToken passwordDigestRequired="false"/>
</xwss:SecurityConfiguration>

The SecurityEnvironmentHandler

The SecurityEnvironmentHandler for this article is again common for both the Client and Server side. On the Client Side it handles the UsernameCallback and PasswordCallback and on the Server Side it handles PasswordValidation.

package simplejdk6ws;

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import com.sun.xml.wss.impl.callback.PasswordCallback;
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
import com.sun.xml.wss.impl.callback.UsernameCallback;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class SecurityEnvironmentHandler implements CallbackHandler {
  
    private static final UnsupportedCallbackException unsupported =
    new UnsupportedCallbackException(null, "Unsupported Callback Type Encountered");
   
    /** Creates a new instance of SecurityEnvironmentHandler */
    public SecurityEnvironmentHandler(String arg) {
    }
   
    private String readLine() throws IOException {
        return new BufferedReader
            (new InputStreamReader(System.in)).readLine();
    }

    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i=0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof PasswordValidationCallback) {
                PasswordValidationCallback cb = (PasswordValidationCallback) callbacks[i];
                if (cb.getRequest() instanceof PasswordValidationCallback.PlainTextPasswordRequest) {
                    cb.setValidator(new PlainTextPasswordValidator());
                   
                } else if (cb.getRequest() instanceof PasswordValidationCallback.DigestPasswordRequest) {
                    PasswordValidationCallback.DigestPasswordRequest request =
                            (PasswordValidationCallback.DigestPasswordRequest) cb.getRequest();
                    String username = request.getUsername();
                    if ("Ron".equals(username)) {
                        request.setPassword("noR");
                        cb.setValidator(new PasswordValidationCallback.DigestPasswordValidator());
                    }
                }
            } else if (callbacks[i] instanceof UsernameCallback) {
                UsernameCallback cb = (UsernameCallback)callbacks[i];
                System.out.println("Username: ");
                String username= readLine();
                if (username != null) {
                    cb.setUsername(username);
                }
               
            } else if (callbacks[i] instanceof PasswordCallback) {
                PasswordCallback cb = (PasswordCallback)callbacks[i];
                System.out.println("Password: ");
                String password = readLine();
                if (password != null) {
                    cb.setPassword(password);
                }
            } else {
                throw unsupported;
            }
        }
    }
   
     private class PlainTextPasswordValidator implements PasswordValidationCallback.PasswordValidator { 
        public boolean validate(PasswordValidationCallback.Request request)
        throws PasswordValidationCallback.PasswordValidationException {
           
            PasswordValidationCallback.PlainTextPasswordRequest plainTextRequest =
            (PasswordValidationCallback.PlainTextPasswordRequest) request;
            if ("Ron".equals(plainTextRequest.getUsername()) &&
            "noR".equals(plainTextRequest.getPassword())) {
                return true;
            }
            return false;
        }
    }
}


This Finishes the implementation of the Service.

Developing the JAVA SE 6 WebService Client

The steps to develop the WebService client for the service we developed just now is as follows :

1. Develop a JAVA SE 6  WebService client by first invoking wsimport supplying it the WSDL location of the WebService developed above.
2. Add a SecurityHandler as the last Handler on the Client. The Security Handler would make use of the XWSS Programmatic API's to secure the outgoing Message. Note that in this article we make use of the Same SecurityHandler for both client and server with different methods getting invoked for server and client side processing.
3. Create an XWSS 2.0 style SecurityConfiguration  that  sends a  Username/Password
4. Develop a SecurityEnvironmentHandler that can handle Username and Password Callback.

The WebService Client Code

package simplejdk6ws;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;

public class SimpleWSClient {
   
    /** Creates a new instance of SimpleWSClient */
    public SimpleWSClient() {
    }
   
    public static void main(String[] args) throws Exception {
       
        try { // Call Web Service Operation
            client.MainService service =
                new client.MainService();
            client.Main port = service.getMainPort();
            List<Handler> chain = new ArrayList<Handler>();
            chain.add(new simplejdk6ws.SecurityHandler("client"));
            ((BindingProvider)port).getBinding().setHandlerChain(chain);
            Iterator<Handler> it = ((BindingProvider)port).getBinding().getHandlerChain().iterator();
            for (; it.hasNext();) {
                Handler h = it.next();
                System.out.println(h.getClass().getName());
            }
            String result = port.sayHello("TOM");
            System.out.println("Result = "+result);
        } catch (Exception ex) {
            // TODO handle custom exceptions here
            throw ex;
        }
    }
   
}

The Client Side SecurityConfiguration

<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true" >
    <xwss:UsernameToken digestPassword="false"/>
</xwss:SecurityConfiguration>

The Client Side SecurityHandler and SecurityEnvironmentHandler

The SecurityHandler and SecurityEnvironmentHandler are essentially the same as were shown above for the Service.

DownLoads Required to Run the Sample

 The Only jar that would ideally be required to make this sample run is either the XWSS 2.0 jar or the XWSS 3.0 jar (xws-security.jar)  from https://xwss.dev.java.net . However as mentioned earlier the XWSS jar's have a dependency on a different packaged version of SAAJ RI (than the one inside JDK 6) and hence you would need to download the latest SAAJ RI from the following Link :  https://wsit.dev.java.net/source/browse/*checkout*/wsit/wsit/lib/runtime/saaj-impl.jar . There would also be a dependency on  mail.jar and activation.jar that would need to be downloaded from other sources.
 
So the README.txt associated with the Sample takes a different approach where it just uses the Metro 1.2 jars to run the sample.

Running the SAMPLE

So you can run the packaged version of this sample by downloading the ZIP file  from :   SecureJDK6WSWithHandlers.zip
Unzip the file and follow the README for instructions on how to run the sample.

When the client is run it would ask for  username and password, so enter "Ron" as the username and "noR" as the password.  And then you should see the Message with UsernameToken being dumped. If you wish to switch off dumping then go to the SecurityConfiguration files shown and make the dumpmessages attributes "false" (they are set to true currently).

Once you have this basic sample running out of the box, you can also try setting the  digestPassword and  passwordDigestRequired attributes to "true" and  experiment with DigestPassword  method, as opposed to the earlier case where the password was going plaintext over the wire.  OfCourse one can always use the former and switch on SSL to secure the communication.

Source Code

The Source Code for the sample is part of the Zip.  In another variation the Client can specify the Username and Password as Properties in the Client Code that are later picked up by the SecurityEnvironmentHandler.  Specifically the client can  do the following :

 client.Main port = service.getMainPort();
 ((BindingProvider)port).getRequestContext().put(com.sun.xml.wss.XWSSConstants.USERNAME_PROPERTY, "Ron");
 ((BindingProvider)port).getRequestContext().put(
com.sun.xml.wss.XWSSConstants.PASSWORD_PROPERTY, "noR");

The SecurityEnvironmentHandler would then be able to access the  Username and Password as follows :

            } else if (callbacks[i] instanceof UsernameCallback) {
                UsernameCallback cb = (UsernameCallback)callbacks[i];
                String username = (String)cb.getRuntimeProperties().get(
com.sun.xml.wss.XWSSConstants.USERNAME_PROPERTY);
                System.out.println("Got Username......... : " + username);
                cb.setUsername(username);
               
      } else if (callbacks[i] instanceof PasswordCallback) {
                PasswordCallback cb = (PasswordCallback)callbacks[i];
                String password = (String)cb.getRuntimeProperties().get(
com.sun.xml.wss.XWSSConstants.PASSWORD_PROPERTY);
                System.out.println("Got Password......... : " + password);
                cb.setPassword(password);
               
      }


The secureClient and secureServer methods of the  SecurityHandler  need to have the following extra line of code to make the above code to work :
                //secureServer
       
ProcessingContext context =  sprocessor.createProcessingContext(message);
        context.getExtraneousProperties().putAll(messageContext);  // add this line to extra to existing code

        //secureClient
        context = cprocessor.createProcessingContext(message);
        context.getExtraneousProperties().putAll(messageContext);
// add this line to extra to existing code





 
 
Close
loading
Please Confirm
Close