WSS4J Documentation is here!

Due to the increasing demand, I attached a work in progress. index.html is the main file (please revise my list of features), api.html is an overview of the WSS4J Java API, axis.html is a detailed step by step tutorial on creating a secure service and a client using WSS4J/Axis.

So far I only did Username Token in the tutorial. Please review/edit so we can maybe publish it on the web site soon (I'm not sure how and where this should be checked in so it shows up on the public web site).

I used package.html as a reference for details on Axis handlers assuming that it will be eventually available and accessible by users (hopefully via a convenient link), so I only listed steps with samples without much explanations as in package.html.

Rami Jaamour
Software Engineer
Web Services Solutions
Parasoft Corporation

"We Make Software Work"



Johan Danforth wrote:

Werner,
Yes, I've looked at that file and I've browsed through most of the
source code that comes with WSS4J without much success I'm afraid. I could
give it another go I guess, but I don't want to spend days to get into it.
Can someone just explain the steps in a pseudo-way maybe? BTW. If there are problems getting WSS4J working with ASP.NET + WSE
2.0, maybe I shouldn't go down that route right now anyway... I need to send
a binary token from java soap (axis) clients to web services built with
ASP.NET, so maybe I should just use normal soap headers for now.
/Johan
-----Original Message-----
From: Werner Dittmann [mailto:[EMAIL PROTECTED] Sent: den 7 januari 2005 13:13
To: Johan Danforth
Cc: [EMAIL PROTECTED]; 'Ted Toth'; fx-dev@ws.apache.org
Subject: Re: tutorials or walkthroughs?
Johan,
sorry for the lack of documentation so far. I'm sure you already
looked
at the "package.html" file in "src/org/apache/ws/axis/security". In
addition
you may have a look at the interop examples.
If you have a complete checkout of wss4j the pls go to the "specs" directory.
This dir contains the "ping.wsdl" file that is used to build the
interop scenarios
as defined by OASIS. The resulting *.java classes (from WSDL2JAVA)
are in
"build/work/org/apache/ws/axis/oasis/ping". The other parts are
located in
"interop/org/apache/ws/axis/oasis/*".
Hope this gets you a step further.
Regards,
Werner
Johan Danforth schrieb:
> Ted, Dims, thanks for the answers.
> First, the need for a basic tutorial is still needed. I still
don't
>understand how to use WSS4J, and I know there are others out there
with the
>same question. I'm in contact with lots of Swedish developers and
solution
>architects that are really interested in WSS4J, but we all need some
help to
>get into it. So please, a simple step-by-step thingy about how to
create a
>console app soap client that uses AXIS WSDL2JAVA stubs, that would
be
>perfect! > I would love to help out with a patch, but again, I need to
get into
>WSS4J first :) Tim, it sounds like you've know lots about this,
can't you
>write down a few simple steps? (Promise to buy you a pint of beer,
coke or
>whatever if we meet ;)
> /Johan
> -----Original Message-----
>From: Davanum Srinivas [mailto:[EMAIL PROTECTED] >Sent: den 6 januari 2005 16:07
>To: Ted Toth
>Cc: Johan Danforth; fx-dev@ws.apache.org
>Subject: Re: tutorials or walkthroughs?
> ><snip>
>
> >





Title: Apache WSS4J API Overview




Apache WSS4J API Overview


Contents



API Overview

WSS4J can be used as a library to provide an API for WS-Security processing. In this case WSS4J does not need to be used with Axis, or even be a part of a deployed web application. The WSS4J API can be invoked directly to create WS-Security headers or process them given a SOAP Envelope DOM Document.

Following is an overview of the main classes and methods for the WSS4J API. Please refer to the java docs for the complete API documentation.

org.apache.ws.security.WSSecurityEngine

Action
Method
Get an instance of security engine
public static org.apache.ws.security.WSSecurityEngine getInstance()
Description
Get a singleton instance of security engine class. If you need to get an instance configured for an older spec (different namespaces) then use the other method which takes org.apache.ws.security.WSSConfig
Parameters
Returns
org.apache.ws.security.WSSecurityEngine
Processes WS-Security Headers in a SOAP Envelope

Action
Method
Verify WSS Headers
java.util.Vector processSecurityHeader(
org.w3c.dom.Document doc,
java.lang.String actor,
javax.security.auth.callback.CallbackHandler cb,
org.apache.ws.security.components.crypto.Crypto crypto
) throws org.apache.ws.security.WSSecurityException
Description
Takes a SOAP Envelope as a W3C Document and verifies the WSS Headers.  This includes Username Token processing, Signature verification, decryption and timestamp verification. In the case of encrypted elements, decryption is performed live on the passed document, i.e., it is transformed into the decrypted format.
Parameters
doc
the SOAP Envelope as W3C DOM Document
actor the engine works on behalf of this actor. Refer to the SOAP specification about actor or role, this may be null.
cb
a callback hander to the caller to resolve passwords during encryption and UsernameToken handling, this may be null.
crypto
the object that implements the access to the keystore and the handling of certificates. A default implementation is included: org.apache.ws.security.components.crypto.Merlin
Returns
java.util.Vector
Vector of org.apache.ws.security.WSSecurityEngineResult, this has the information resulting from the processing, such as the principal, SAML token, etc.

org.apache.ws.security.message.WSBaseMessage

Action
Method
Set the Signature/Encryption parts
public void setParts(java.util.Vector parts)
Description
Takes a vector of org.apache.ws.security.WSEncryptionPart.
Parameters
doc
the SOAP Envelope as W3C DOM Document
crypto
the object that implements the access to the keystore and the handling of certificates. A default implementation is included: org.apache.ws.security.components.crypto.Merlin
Returns
org.w3c.dom.Document
the SOAP Envelope Signed. The signed elements depend on the signature parts that are specified by the WSBaseMessage.setParts(java.util.Vector parts) method

org.apache.ws.security.message.WSSignEnvelope (extends WSBaseMessage)

Action
Method
Signs a SOAP Envelope
public org.w3c.dom.Document build(
org.w3c.dom.Document doc,
org.apache.ws.security.components.crypto.Crypto crypto
) throws org.apache.ws.security.WSSecurityException
Description
Takes a SOAP Envelope as a W3C Document and adds WSS Signature header to it. The signed elements depend on the signature parts that are specified by the WSBaseMessage.setParts(java.util.Vector parts) method. By default, SOAP Body is signed
Parameters
doc
the SOAP Envelope as W3C DOM Document
crypto
the object that implements the access to the keystore and the handling of certificates. A default implementation is included: org.apache.ws.security.components.crypto.Merlin
Returns
org.w3c.dom.Document
the SOAP Envelope signed.

org.apache.ws.security.message.WSAddTimestamp (extends WSBaseMessage)

Action
Method
Add a Timestamp Token to a SOAP Envelope
public org.w3c.dom.Document build(
org.w3c.dom.Document doc,
 int ttl)
Description
Takes a SOAP Envelope as a W3C Document and adds a Timestamp header to it. Please refer to the WS specification 1.0. chapter 10 / appendix A.2

Parameters
doc
the SOAP Envelope as W3C DOM Document
ttl
(time to live) This is the time difference in seconds between the Created and the Expires in Timestamp, set to zero if Expires should not be added.
Returns
org.w3c.dom.Document
the SOAP Envelope with the Timestamp added

org.apache.ws.security.message.WSEncryptBody (extends WSBaseMessage)

Action
Method
Encrypt a SOAP Envelope
public org.w3c.dom.Document build(
org.w3c.dom.Document doc,
org.apache.ws.security.components.crypto.Crypto crypto
) throws org.apache.ws.security.WSSecurityException
Description
Takes a SOAP Envelope as a W3C Document and adds WSS Encryption header to it. Unlike what the class name might imply, this can be used to encrypt elements in the SOAP Header, such as Username Tokens or other arbitrary elements. The encrypted elements depend on the signature parts that are specified by the WSBaseMessage.setParts(java.util.Vector parts) method. By default, SOAP Body is encrypted
Parameters
doc
the SOAP Envelope as W3C DOM Document
crypto
the object that implements the access to the keystore and the handling of certificates. A default implementation is included: org.apache.ws.security.components.crypto.Merlin
Returns
org.w3c.dom.Document
the SOAP Envelope encrypted.

org.apache.ws.security.message.WSAddUsernameToken (extends WSBaseMessage)

Action
Method
Add a Username Token to a SOAP Envelope
public org.w3c.dom.Document build(
org.w3c.dom.Document doc,
java.lang.String username,
java.lang.String password)
Description
Takes a SOAP Envelope as a W3C Document and adds a Username Token header to it. Use setPasswordType(java.lang.String pwType) to choose between plain text passwords and digested ones.
Parameters
doc
the SOAP Envelope as W3C DOM Document
username
the username to use
password
the password to use (a plain text string)
Returns
org.w3c.dom.Document
the SOAP Envelope with the username token header added

org.apache.ws.security.message.WSSAddSAMLToken (extends WSBaseMessage)

Action
Method
Add a SAML Token to a SOAP Envelope
public org.w3c.dom.Document build(
org.w3c.dom.Document doc,
 org.opensaml.SAMLAssertion assertion)
Description
Takes a SOAP Envelope as a W3C Document and adds a SAML Assertion Token header to it. Please refer to the OpenSAML documentation on how to construct SAML assertions.
Parameters
doc
the SOAP Envelope as W3C DOM Document
assertion
the SAML assertion to add
Returns
org.w3c.dom.Document
the SOAP Envelope with the SAML assertion header added

Examples

Sign the SOAP Body

Document envelope = ...
WSSignEnvelope signer = new WSSignEnvelope();
Crypto crypto = CryptoFactory.getInstance("crypto.properties");
Vector parts = new Vector();
WSEncryptionPart part = new WSEncryptionPart(soapConstants.getBodyQName().getLocalPart(),
                                             soapConstants.getEnvelopeURI(),
                                             "Content");
parts.add(part);
signer.setParts(parts); // this is optional since the body is signed by default
envelope = signer.build(envelope, crypto);

Encrypt the SOAP Body

Document envelope = ...
WSEncryptBody encryptor = new WSEncryptBody();
Crypto crypto = CryptoFactory.getInstance("crypto.properties");
Vector parts = new Vector();
WSEncryptionPart part = new WSEncryptionPart(soapConstants.getBodyQName().getLocalPart(),
                                             soapConstants.getEnvelopeURI(),
                                             "Content");
parts.add(part);
encryptor.setParts(parts);
// this is optional since the body is encrypted by default
envelope = encryptor.build(envelope, crypto);

Process WSS Header and Check the Results

Document envelope = ...
WSSecurityEngine secEngine = WSSecurityEngine.getInstance();
Crypto crypto = CryptoFactory.getInstance("crypto.properties");
// javax.security.auth.callback.CallbackHandler
// please refer to the tests for examples of callback handlers
CallbackHandler cb = new MyCallbackHandler();
Vector results = secEngine.processSecurityHeader(envelope, null, cb, crypto);
for (int i = 0; i < results.size(); i++) {
    WSHandlerResult hResult = (WSHandlerResult)results.get(i);
    String actor = hResult.getActor();
    Vector hResults = hResult.getResults();
    for (int j = 0; j < hResults.size(); j++) {
        WSSecurityEngineResult eResult = (WSSecurityEngineResult)hResults.get(j);
        // Note: an encryption action does not have an associated principal
        // only Signature and UsernameToken actions return a principal
        if (eResult.getAction() != WSConstants.ENCR) {
            System.out.println(eResult.getPrincipal().getName());
        }
    }
}

Title: Axis Deployment Tutorial

Apache WSS4J

Axis Deployment Tutorial


Contents

  • Introduction
  • Prerequisties
  • Steps
    • Username Token

Introduction

WS4J can be used for securing web services deployed in virtually any application server, but it includes special support for Axis. WSS4J ships with handlers that can be used in Axis-based web services for an easy integration. These handlers can be added to the service deployment descriptor (wsdd file) to add a WS-Security layer to the web service. This is a step by step tutorial for deploying a simple service with Username Token.

Prerequisties

Axis 1.2 installed and configured on a Tomcat Server.  This tutorial was performed on a Linux machine with Tomcat 5.5.4/Java 1.5.0, however, the setup should be similar on other application servers, or other operating systems (like Windows) unless we stated otherwise.

Steps

    Installing WSS4J

  1. Download the WSS4J binaries or build it from sources
  2. Copy the contents of the WSS4J lib directory to your Axis WEB-INF/lib directory. Many jar files will already exist. Most of them will already exist there but you can just overwrite them all.
  3. You may need to restart Tomcat unless you have automatic deployment/class loading turned on. Check the Axis Happiness Page (typically at http://localhost:8080/axis), make sure that the XML Security (xmlsec.jar) is listed under the "Optional Components" section.

Creating the Service

    1. This tutorial will secure the StockQuoteService which ships with Axis. Unless you have one already, create a deployment descriptor (deploy.wsdd) file with the following contents:

    <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
     <service name="stock-wss-01" provider="java:RPC" style="document" use="literal">
      <parameter name="className" value="samples.stock.StockQuoteService"/>
      <parameter name="allowedMethods" value="getQuote"/>
      <parameter name="scope" value="application"/>
     </service>
    </deployment>

  1. deploy the service (using AxisAdmin):
    java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd

Creating the Client

  1. Use WSDL2Java to generate the client service bindings:
    java org.apache.axis.wsdl.WSDL2Java -o . -Nhttp://fox:8080/axis/services/stock-wss-01 samples.stock.client http://fox:8080/axis/services/stock-wss-01?wsdl

    A bunch of java classes will be created under samples/stock/client, including the StockQuoteServiceServiceLocator.

  2. Write a simple java client that uses the generated service locator. For example:

    package samples.stock.client;

    import java.rmi.RemoteException;
    import javax.xml.rpc.ServiceException;

    public class StockServiceClient {
        public StockServiceClient() {
        }
        public static void main(String[] args) throws ServiceException, RemoteException {
            if (args.length == 0) {
                System.out.println("Usage:\njava StockServiceClient [symbol]");
                return;
            }
            StockQuoteServiceService locator = new StockQuoteServiceServiceLocator();
            StockQuoteService service = locator.getStockWss01();
            float quote = service.getQuote(args[0]);
            System.out.println("stock quote service returned " + args[0] + ": " + quote);
        }
    }

  3. run the client:
    java samples.stock.client.StockServiceClient IBM

    If all went well, you should get the result:

    stock quote service returned IBM: 95.68

Username Token

Configuring the Service

  1. Modify the deployment descriptor you created above to look like this:
    <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
     <service name="stock-wss-01" provider="java:RPC" style="document" use="literal">
      <requestFlow>
       <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
        <parameter name="passwordCallbackClass" value="PWCallback"/>
        <parameter name="action" value="UsernameToken"/>
       </handler>
      </requestFlow>
      <parameter name="className" value="samples.stock.StockQuoteService"/>
      <parameter name="allowedMethods" value="getQuote"/>
      <parameter name="scope" value="application"/>
     </service>
    </deployment>

    WSDoAllReceiver is an Axis handler that can be located in wss4j.jar. This is the standard way to deploy an Axis handler. For more details please refer to the Axis handler for WSS4J documentation.

  2. Create a class named PWCallback.java and compile it into your Axis WEB-INF/classes directory. In this example I used the default package for simplicity, but you might need to use the fully qualified class name (be consistent with the deployment descriptor).

    The following code snippet shows a simple password callback class:

    import java.io.IOException;
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException;
    import org.apache.ws.security.WSPasswordCallback;

    public class PWCallback implements CallbackHandler {
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            for (int i = 0; i < callbacks.length; i++) {
                if (callbacks[i] instanceof WSPasswordCallback) {
                    WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
                    // set the password given a username
                    if ("wss4j".equals(pc.getIdentifer())) {
                        pc.setPassword("security");
                    }
                } else {
                    throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
                }
            }
        }
    }



  3. Redeploy the service. Your service should now be expecting a WSS Username Token in in the incoming requests, and clients should send the username "wss4j" and password "security" to get through.

Configuring the Client

  1. run the client we created again:
    java samples.stock.client.StockServiceClient IBM

    You should now get an error:

    Exception in thread "main" AxisFault
     faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException
     faultSubcode:
     faultString: WSDoAllReceiver: Request does not contain required Security header

    This is because your client is not configured to send a Username Token yet, so the service is rejecting the request.

  2. Create a deployment descriptor file (client_deploy.wsdd) for the client:

    <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
     <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
      <globalConfiguration >
       <requestFlow >
        <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
         <parameter name="action" value="UsernameToken"/>
         <parameter name="user" value="wss4j"/>
         <parameter name="passwordCallbackClass" value="samples.stock.client.PWCallback"/>
         <parameter name="passwordType" value="PasswordDigest"/>
        </handler>
       </requestFlow >
      </globalConfiguration >
    </deployment>


  3. Create the samples.stock.client.PWCallback class:

    package samples.stock.client;

    import java.io.IOException;
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException;
    import org.apache.ws.security.WSPasswordCallback;

    /**
     * PWCallback for the Client
     */
    public class PWCallback implements CallbackHandler {

        /**
         * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
         */
        public void handle(Callback[] callbacks) throws IOException,
                        UnsupportedCallbackException {
            for (int i = 0; i < callbacks.length; i++) {
                if (callbacks[i] instanceof WSPasswordCallback) {
                    WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
                    // set the password given a username
                    if ("wss4j".equals(pc.getIdentifer())) {
                        pc.setPassword("security");
                    }
                } else {
                    throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
                }
            }
        }
    }

  4. Define the system property axis.ClientConfigFile for your client:

    java -Daxis.ClientConfigFile=client_deploy.wsdd -classpath $AXISCLASSPATH samples.stock.client.StockServiceClient

    Make sure that your classpath includes the jar files under WEB-INF/lib.

    Another way to do this is to specify the wsdd file in your StockServiceClient to the service locator programmatically:

    ...
    import org.apache.axis.EngineConfiguration;
    import org.apache.axis.configuration.FileProvider;
    ...

    EngineConfiguration config = new FileProvider("client_deploy.wsdd");
    StockQuoteServiceService locator = new StockQuoteServiceServiceLocator(config);
    ...

  5. Run the client, you should get no errors:

    stock quote service returned IBM: 95.7

    Your client is now sending a Username Token in the wsse request header with the username "wss4j" (see client_deploy.wsdd) and password "security" (see the PWCallback implementation).

    Another way to do this is to have the client application set the username and CallbackHandler implementation programmatically instead of client_deploy.wsdd:

    ...
    import org.apache.axis.client.Stub;
    ...

    Remote remote = locator.getPort(StockQuoteService.class);
    Stub axisPort = (Stub)remote;
    axisPort._setProperty(UsernameToken.PASSWORD_TYPE, WSConstants.PASSWORD_DIGEST);
    axisPort._setProperty(WSHandlerConstants.USER, "wss4j");
    axisPort._setProperty(WSHandlerConstants.PW_CALLBACK_REF, pwCallback);

    where "pwCallback" is a reference to a PWCallback implementation. See the Axis handler for WSS4J documentation for more details on this.

  6. Try modifying your client's PWCallback to return the wrong password, or send the wrong username. The service should reject your requests.



Title: WSS4J Documentation

Apache WSS4J Documentation


Contents



What is WSS4J?

Apache WSS4J is an implementation of the OASIS Web Services Security (WS-Security) from OASIS Web Services Security TC.

WSS4J implements

WSS4J can also be configured to emulate previous WSS spec implementations with older namespaces, such as WebSphere 5.1 and WebLogic 8.1 SP2.

WS-Security Features

WSS4J can generate and process the following SOAP Bindings:

    • XML Security
      • XML Signature
      • XML Encryption
    • Tokens
      • Username Tokens
      • Timestamps
      • SAML Tokens
WSS4J supports X.509 binary certificates and certificate paths.

WSS4J Use Cases

WSS4J API

Please refer to the API Overview for details.

WSS4J on Axis

Please refer to the the Axis Deployment Tutorial for details.


Reply via email to