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.
- Extend the
WSConnectionclass and override theconfigureExecutor()class to perform additional configuration on theWebServiceExecutor.
Code sample
@Override
protected void configureExecutor(WebServiceOperation operation, String operationName, WebServiceExecutor executor)
{
super.configureExecutor(operation, operationName, executor);
// add HTTP Basic Auth security
configureUsernameWSSecurity(executor);
}
- Ensure that the
connector-d.xmlhasusernameandpasswordfields. If you are using the supplied exampleconnector-d.xmlfile, 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.
- Extend the
WSConnectionclass and override theconfigureExecutor()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);
}
- Ensure that the
connector-d.xmlhasusernameandpasswordfields. If you are using the supplied exampleconnector-d.xmlfile, 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
- Extend the
WSCacheclass and add a method for retrieving the login token. TheWSCacheis 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
- Extend the
WSConnectionclass and add a method for creatingWebServiceRequestinstances.
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);
}
- Use this new method in the various operation implementation classes to generate the
WebServiceRequest. For example, to use this method for anEXECUTEoperation, extend theWSExecuteOperationclass and override thecreateRequest()method.
Code sample
@Override
protected WebServiceRequest createRequest(InputStream reqStream)
throws Exception
{
return getConnection().createRequest(reqStream);
}
Use the token in the SOAP body
- Extend the WSConnection class and add a method for creating
WebServiceRequestinstances.
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);
}
}
- Follow step 2 in the "Use the token in the SOAP header" example in this topic.
Was this topic helpful?