Skip to main content
Version: 3.14.x.x LTS

SOAP/HTTPS proxying - configuration

nevisProxy automatically detects a SOAP request (the SOAPAction HTTP-header must be set to identify a SOAP version 1.1 message and a "Content-Type" header must be set to "application/soap+xml" to identify a SOAP version 1.2 message), and in case of an error it responds with a SOAP-Fault. But for WSS to work as described above we need to configure nevisProxy and nevisAuth.

IdentityCreationFilter

The IdentityCreationFilter has to forward the SOAP message (at least the SOAP-Header) to the authentication service. In case the proxy has to handle large SOAP requests, it may be necessary to reduce the authentication overhead by only forwarding the SOAP header to the authentication server. This is achieved by configuring the following:

<init-param>
<param-name>OnlySoapHeader</param-name>
<param-value>true</param-value>
</init-param>

If set to true, we also keep the DOM-tree in the request for later processing by the DelegationFilter. This is the preferred usage, nevertheless the default value is set to false to ensure backward compatibility. If set to false the SOAP message is not parsed by nevisProxy and nevisAuth gets the complete SOAP-Envelope. When working with the X.509 token profile and signed body data, this optimization needs to stay disabled and in case of large SOAP bodies the init-param BodyReadSize has to be increased ).

DelegationFilter

This filter takes charge of the SOAP/WSS-Security header substitution. In the case below, we set the Nevis SecToken into the SOAP/WSS-Security header (UsernameToken will be removed).

<init-param>
<param-name>DelegateSOAPSubstitutedSecurityHeader</param-name>
<param-value>
AUTH:user.auth.SecToken
</param-value>
</init-param>

To set a SAML assertion for the authenticated user, configure 'AUTH:saml.Assertion' instead and make sure the nevisAuth AuthEngine is configured accordingly (see below).

LoginRendererServlet

The login renderer has to generate a SOAP fault, if an authentication fails. This can be achieved by using a login renderer in the corresponding IdentityCreationFilter, with the following entry:

<init-param>
<param-name>RenderingProvider</param-name>
<param-value>localBuiltin:auto</param-value>
</init-param>

An authentication failure the returns a SOAP fault with a detail element, describing available authentication failure information.

Error handling

As the proxy itself may encounter problems, when processing SOAP requests, nevisProxy produces its own SOAP faults. These SOAP faults arise under e.g. the following circumstances:

  • Session-Overflow problems, when authentication is required
  • Communication problems (Network, Security) with the authentication server, when authentication is required
  • Communication problems (Network, Security) with the web service provider
  • Authentication failure, when accessing a protected resource and invalid credentials were provided.

A failure message returns a HTTP status, reflecting the failure and a text/xml document, containing a complete SOAP response with a SOAP fault entry. The following sample shows a (slightly reduced) error response, stating an unavailable backend server:

< HTTP/1.1 502 Bad Gateway
< Content-Type: text/xml
< Content-Length: 423
<?xml version="1.0" encoding="utf-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Upstream server is not available</faultstring>
<faultactor>https://proxy.company.com:443/webservices/</faultactor>
<detail>Upstream server is not available</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The <faultstring> element contains a short error message, whereas the <detail> element may contain further internal details of the error. In case of authentication, this element in addition holds the authentication protocol details, as provided by the nevisAuth <Gui> descriptor. Accessing a web service location with invalid or missing credentials triggers an error message similar to this one:

< HTTP/1.1 403 Forbidden
< Set-Cookie: Navajo=MuyD7UQJUyLuj/u+7TZX7K9Wh0lhTHpo+EbOUWRb9AY7hqPeKAbmphk-; path=/; secure
< Content-Type: text/xml
< Content-Length: 936
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Authentication required (realm='SSO')</faultstring>
<faultactor>https://proxy.company.com:443/webservices/</faultactor>
<detail>
<Gui name="AuthLdapDialog" label="Login failed">
<GuiElem name="lasterror" type="error" label="Invalid input." value="1" />
<GuiElem name="isiwebuserid" type="text" label="User ID" value="" />
<GuiElem name="isiwebpasswd" type="pw-text" label="Password" value="" />
<GuiElem name="submitLdap" type="button" label="Login" value="" />
</Gui>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Authentication input may be provided using a WSS token (e.g. a user or X509 token) in the SOAP header, an X.509 client certificate on the SSL/TLS transport or the HTTP basic authentication mechanism.

The following table provides an overview over the error codes:

EventHTTPSOAP faultSOAP fault detail
Proxy internal failure (e.g. session cache overflow, badly structured HTTP request etc.)400 .. 500Clientunstructured message
Backend failureany HTTP status provided by backendServerunstructured message
Backend unavailable502Serverunstructured message
Authentication failure403ClientnevisAuth <Gui> descriptor, containing an 'error' field with an authentication error code (see nevisAuth reference guide or your site documentation for possible error code)

nevisAuth

Also refer to the nevisAuth Reference Guide. We setup the AuthEngine with a SOAP domain. This domain never does any user interaction, therefore all AuthStates are configured with the attribute 'final=false'. The first state to process is the UsernameToken state, where username and password are extracted from the UsernameToken header in the SOAP/WSS message. The values are delegated to an arbitrary AuthState as an authentication input. As a post-processing we add a SAML assertion to the response.

<Domain name="soap" default="false">
<Entry method="authenticate" state="UsernameToken"/>
</Domain>
<AuthState name="UsernameToken"
class="ch.nevis.esauth.auth.states.wss.UsernameToken" final="false">
<ResultCond name="default" next="TestUsernamePassword"/>
<Response value="AUTH_ERROR">
<Gui name="AuthNoWssToken"/>
/Response>
/AuthState>

<AuthState name="TestUsernamePassword"
class="ch.nevis.esauth.auth.states.standard.UseridPasswordAuthenticateState"
authLevel="auth.test" final="false">
<ResultCond name="ok" next="SAMLAssertion"/>
<Response value="AUTH_ERROR">
<Gui name="AuthUidPwDialog" label="Test Login">
<GuiElem name="lasterror" type="error" label="${notes.lasterrorinfo}"

value="${notes.lasterror}"/>
<GuiElem name="isiwebuserid" type="text" label="Login ID"

value="${notes.loginid}"/>
<GuiElem name="isiwebpasswd" type="pw-text" label="Password"/>
<GuiElem name="submit" type="button" label="submit.button.label" value="Login"/>
</Gui>
</Response>
</AuthState>

<AuthState name="SAMLAssertion"
class="ch.nevis.esauth.auth.states.wss.SAMLAssertion">
<Response value="AUTH_DONE">
<Gui name="NoDialog"/>
</Response>
<property name="keystorefile" value="keystore.jks"/>
<property name="keystorealias" value="myalias"/>
<property name="keystorepassword" value="mypassword"/>
<property name="saml.assertion.attribute.loginid" value="${sess.ch.nevis.session.loginid}"/>
<!--
<property name="saml.assertion.attribute.<name>" value="${sess.<name>}"/>
-->
</AuthState>