Waiting for engine...
Skip to main content

Security

Authentication is typically the first challenge to address when invoking a web service.

HTTP Basic Auth

HTTP Basic Auth support is built into the framework, so this implementation is fairly simple.

  1. Extend the WSConnection class and override the configureExecutor() class to perform additional configuration on the WebServiceExecutor.
Code sample
@Override
protected void configureExecutor(WebServiceOperation operation, String operationName, WebServiceExecutor executor)
{
super.configureExecutor(operation, operationName, executor);

// add HTTP Basic Auth security
configureUsernameWSSecurity(executor);
}
  1. Ensure that the connector-d.xml has username and password fields. If you are using the supplied example connector-d.xml file, uncomment these fields.

WS-Security with TEXT/DIGEST password

Similar to HTTP Basic Auth, WS-Security TEXT/DIGEST support is built into the framework. This implementation is fairly simple.

  1. Extend the WSConnection class and override the configureExecutor() class to perform additional configuration on the WebServiceExecutor.
Code sample
@Override
protected void configureExecutor(WebServiceOperation operation, String operationName, WebServiceExecutor executor)
{
super.configureExecutor(operation, operationName, executor);

// add username TEXT WS-Security (or use DIGEST if desired)
configureUsernameWSSecurity(UserTokenPasswordType.TEXT, executor);
}
  1. Ensure that the connector-d.xml has username and password fields. If you are using the supplied example connector-d.xml file, uncomment these fields.

Login tokens

A common authentication mechanism is to have a login operation return a token, possibly with an expiration time. You need to acquire the token, handle token expiration, and utilize the token in a subsequent request.

Acquire the token

  1. Extend the WSCache class and add a method for retrieving the login token. The WSCache is a long-lived class that is also responsible for handling token expiration. In this example, the token is forced to expire after 25 minutes of inactivity.
Code sample
     // token timeout value, based on an expected token lifetime of ~30 minutes
private static final long TOKEN_TIMEOUT = 25L * 60L * 1000L;

// store the login token as a String and expire it after TOKEN_TIME milliseconds of inactivity
private final ExpiringValue<String> _loginToken = new InactiveExpiringValue<String>(TOKEN_TIMEOUT);

public synchronized String getLoginToken(WSConnection conn)
throws WebServiceException
{
String token = _loginToken.get();

if(token == null) {
token = login(conn);
_loginToken.set(token);
}

return token;
}

private String login(WSConnection conn)
throws WebServiceException
{
// ... do login work here (note we probably need the WSConnection for access to user credentials and common
// code for interacting with the webservice) ...
return token;
}

Use the token in the SOAP header

  1. Extend the WSConnection class and add a method for creating WebServiceRequest instances.
Code sample
public WebServiceRequest createRequest(InputStream reqStream)
throws WebServiceException
{
// grab the current login token (logging in if necessary)
String loginToken = getCache().getLoginToken(this);

// ... create login token header element ...
Element loginTokenHeader = ...;

return new WebServiceRequest(reqStream, loginTokenHeader);
}
  1. Use this new method in the various operation implementation classes to generate the WebServiceRequest. For example, to use this method for an EXECUTE operation, extend the WSExecuteOperation class and override the createRequest() method.
Code sample
@Override
protected WebServiceRequest createRequest(InputStream reqStream)
throws Exception
{
return getConnection().createRequest(reqStream);
}

Use the token in the SOAP body

  1. Extend the WSConnection class and add a method for creating WebServiceRequest instances.
Code sample
public WebServiceRequest createRequest(InputStream reqStream)
throws WebServiceException
{
// grab the current login token (logging in if necessary)
String loginToken = getCache().getLoginToken(this);

try {
// convert the request stream to DOM
Document reqDoc = XMLUtil.parseXML(reqStream);

// ... manipulate the DOM to insert the login token where required ...
return new WebServiceRequest(reqDoc);

} catch(Exception e) {
throw new WebServiceException("Could not parse request document", e);
}
}
  1. Follow step 2 in the "Use the token in the SOAP header" example in this topic.
On this Page