Connection section
The connection section contains all the information required to contact a remote service. More specifically:
Element | Description | Mandatory |
---|---|---|
<url> | The address of the web service, such as http://localhost:8080/mock/mock . It is possible to parameterize the URL as explained here. | Yes |
<keystore> | A keystore that contains one private key and certificate entry. This entry will be used for mutual TLS when the client needs to provide a certificate to authenticate itself towards the HTTP server. | No |
<truststore> | A keystore that contains certificates that the connector will trust. This should only be needed if your HTTP server has a certificate which is not in Java’s or the operating system’s truststore already. | No |
<connectionKey> | Specifies an XACML attribute that will provide the value to replace a placeholder in a parameterized URL. See here. | No |
<header> | Specifies the HTTP header that will be added to the HTTP request. For instance, the Accept or Content-Type headers used for HTTP content negotiation. Info: For a full list of HTTP headers, click hereOpens in a new tab. | No |
<method> | The HTTP request method, GET or POST . The default is POST . Important: The value is case-insensitive. | No |
<authentication> | Specifies in what way the connector will authenticate itself with the HTTP server. Click here for details. | No |
<acceptedHttpCode> | Specifies an additional HTTP Response Status Code to be accepted as successful, besides code 200 which is always accepted as successful.The connector will return the body of any HTTP response that has a status code accepted as successful. If the status code is not accepted as successful, the connector will either ignore the response or fail. The <ignoredHttpCode> element below controls which status codes are ignored. When a response is ignored the connector will return an empty value for the relevant attribute, instead of returning an error.Note: There can be several instances of this element. | No |
<ignoredHttpCode> | Specifies an HTTP Response Status Code that is not accepted as successful but should be ignored and not considered an error. When the status code of an HTTP response is not accepted as successful, the connector will normally return an error, unless the code is specified as ignored. When the status code of an HTTP response is not accepted as successful and it is specified as ignored, the connector will return an empty value for the relevant attribute, instead of returning an error. The <acceptedHttpCode> element above controls which status codes are accepted as successful.Note: There can be several instances of this element. | No |
<retryableHttpCode> | Specifies an HTTP Response Status Code that should trigger a retry attempt utilizing <retryStrategy> . For example: <retryableHttpCode>503</retryableHttpCode> Note: There can be several instances of this element. | No |
<retryableException> | In case no HTTP Response Status Code is returned, an exception is thrown. This element allows you to specify which exception(s) should trigger a retry attempt utilizing <retryStrategy> .See the Retryable exception section below for details. Note: There can be several instances of this element. | No |
<retryStrategy> | Defines the strategy for handling retries triggered by <retryableHttpCode> and <retryableException> . It includes the following child elements: - <maxRetries> - <interval> - <maxTimeForRetries> See the Retry strategy section below for details. | No |
Finally, the <connection>
element can have the following flags:
insecure
of Boolean typeThis flag indicates whether TLS certificates received from the server are validated or not, when using a secure connection (HTTPS). The default value is
false
.ImportantThis flag is a security risk and should not be enabled in production environments. It is only intended to be used for troubleshooting in development environments. When enabled, the connector will log a warning as a reminder of the security risk.
useWindowsAuthentication
of Boolean typeIndicates whether the connector will use proprietary
Windows authentication
when connecting to a Microsoft Windows server. When enabled, this feature is normally used together with theNTLM
authentication mode setting in the<authentication>
configuration section.noteThis flag is deprecated and remains in the XML configuration for compatibility reasons. Ιf set to
true
an error will be thrown.
The URL
Format
The URL in the HTTP Attribute Connector can be static or dynamic. A static URL means that all HTTP calls made by the connector will use exactly the same URL. A dynamic URL is a URL where different parts can come from other XACML attributes. This is particularly useful for REST calls where the URL is typically parameterized.
Let’s take for instance a REST call to an API which provides information about users e.g. https://example.com/v1/users
. An HTTP GET call to https://example.com/v1/users
would return the entire user set. For example:
<list>
<User>
<id>1e36aef0-4e71-11e6-898d-f1931def5a85</id>
<firstName>Joe</firstName>
<lastName>Blog</lastName>
<role>manager</role>
</User>
<User>
<id>33cd91c1-4e71-11e6-898d-f1931def5a85</id>
<firstName>Alice</firstName>
<lastName>Swanson</lastName>
<role>student</role>
</User>
</list>
A parameterized URL where a user’s identifier is passed in would be used to retrieve that user’s profile only. For instance an HTTP GET call to https://example.com/v1/users/33cd91c1-4e71-11e6-898d-f1931def5a85
would return:
<User>
<id>33cd91c1-4e71-11e6-898d-f1931def5a85</id>
<firstName>Alice</firstName>
<lastName>Swanson</lastName>
<role>student</role>
</User>
To create a parameterized URL in the HTTP Attribute Connector configuration, define placeholders in the URL using curly braces ({
and }
) surrounding a number representing the index of the key. Indexes start with 0. Indexes can be used multiple times. There must be as many connectionKey
elements specified as there are unique key indexes. The connectionKey
elements are all of type xacmlAttribute
.
Example
The example below provides a URL that has a single dynamic part at the end, {0}
. The Attribute Connector will replace the dynamic part with values from the XACML attribute example.userId
.
<connection>
<url>https://xacml.apispark.net/v1/users/{0}</url>
<connectionKey>
<xacmlAttribute Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="example.userId" DataType="http://www.w3.org/2001/XMLSchema#string"/>
</connectionKey>
<method>GET</method>
</connection>
Authentication
There are different ways to authenticate an HTTP request. Currently, this connector simplifies authenticating HTTP requests using Basic authentication, Bearer token authentication, and OAuth 2.0 / OIDC authentication. When an authentication mode has been set, appropriate HTTP authentication headers will be automatically created and do not need to be specified manually with a header
element. Also, in more complex authentication modes, appropriate access tokens will be automatically retrieved from an external identity provider.
The authentication mode used is determined by setting the authenticationMode
to one of the values Basic
, Bearer
, or OAuth2
. Each mode requires its own set of configuration data, as exemplified below.
When utilizing OAuth 2.0, to leverage the HTTP Attribute Connector's ability to proactively renew the access token before it expires, ensure that the authorization server includes the expires_in
parameter in its response along with the token. For details, refer to the RFC 6749 specification document.
Format
The following example shows how to configure the HTTP requests to use Basic Authentication credentials:
<authentication authenticationMode="Basic">
<username>user1</username>
<password>user1_password</password>
</authentication>
<username>
: a Basic Authentication username<password>
: a Basic Authentication password
The following example shows how to configure the HTTP requests to use Bearer token credentials:
<authentication authenticationMode="Bearer">
<token>secret-token</token>
</authentication>
<token>
: a string representing a "Bearer" access token.
The following example shows how to configure the HTTP requests to use OAuth2 or OpenID Connect (OIDC) credentials:
<authentication authenticationMode="OAuth2">
<tokenUrl>sts-server:1234/token</tokenUrl>
<clientId>this_apps_identifier</clientId>
<clientSecret>this_apps_secret</clientSecret>
<scope>api:scope</scope>
</authentication>
<tokenUrl>
: the URL of an access token retrieval endpoint. This element is required.<clientId>
: the application (client) identity used to retrieve access tokens. This element is required.<clientSecret>
: the secret corresponding to the application identity used to retrieve access tokens. This element is required.<scope>
: a string representing access grant scopes that may be required by the token service. This element is optional.
By default, the access tokens are retrieved sending the application credentials in HTTP headers. Some identity provider may require the credentials to be sent in the body of the request instead. In these cases, the tokenServiceAuthenticationMode
attribute can be used to specify the authentication mode used when retrieving access tokens, as shown below.
<authentication authenticationMode="OAuth2"
tokenServiceAuthenticationMode="Form">
<tokenUrl>sts-server:1234/token</tokenUrl>
<clientId>this_apps_identifier</clientId>
<clientSecret>this_apps_secret</clientSecret>
</authentication>
authenticationMode
: sets the authentication mode used when requesting an OAuth2 access token toForm
. This attribute is optional, and it defaults toBasic
.
Details
The <authentication>
element can have the following attributes:
One mandatory attribute called
authenticationMode
. The only supported values areBasic
,Bearer
, andOAuth2
(case-sensitive).noteNLTM
mode was also supported in the past, however this is no longer the case. Using it will result in an error.One optional attribute called
tokenServiceAuthenticationMode
. This attribute has an effect only when using theOAuth2
authentication mode. The values supported areBasic
andForm
(case-sensitive). This attribute controls the authentication mode used when requesting an OAuth2 access token. InBasic
mode, the credentials (clientId
andclientSecret
) will be sent in a request header, following Basic Authentication conventions. InForm
mode, the credentials will be sent as form fields in the body of the request. If the attribute is omitted, the value defaults toBasic
.
The authentication section also includes the following elements:
Element | Description | Mandatory |
---|---|---|
<tokenUrl> | Required for the OAuth2 authentication mode. It should contain the URL of an access token retrieval endpoint. In the OAuth2 mode, the connector will handle the retrieval of the access token. It will retrieve the access token using an application identifier (specified by the clientId element), a secret (specified by the clientSecret element), and optionally, a specific access scope (specified by the scope element). It will also handle the setting of an appropriate HTTP authentication header, using the token retrieved, so this header does not need to be specified manually with a header element. | No |
<clientId> | This element along with clientSecret , are required for the OAuth2 authentication mode. This is the application (client) identifier used for authentication against the token retrieval endpoint specified in the tokenUrl element. | No |
<clientSecret> | This element along with clientId are required for the OAuth2 authentication mode. This is a string representing a secret corresponding to the identifier specified in the clientId element. It is used for authentication against the token retrieval endpoint specified in the tokenUrl element. | No |
<scope> | Optional for the OAuth2 authentication mode. The token retrieval service can support different "scopes", which are a way to limit the amount of access to be granted in an access token. | No |
<token> | Required for the Bearer authentication mode. It should contain a security token. In the Bearer mode, an appropriate HTTP authentication header will be automatically created, and does not need to be specified manually with a header element. | No |
<fetchAuthTokenEagerly> | When set to true , the HTTP Attribute Connector fetches the access token proactively upon initialization. Otherwise, it waits until a request gets rejected with a 401 Unauthorized response status code before fetching the access token.The default is false which triggers the latter behavior. | No |
<username> | This element along password , are required for the Basic authentication mode. In this mode, the appropriate HTTP authentication headers will be automatically created, and do not need to be specified manually with header elements. | No |
<password> | This element along username are required for the Basic authentication mode. In this mode, the appropriate HTTP authentication headers will be automatically created, and do not need to be specified manually as header elements. | No |
<domain> | Used in the NTLM authentication mode.NOTE: Using this element will throw an error because the NTLM mode is no longer supported. It remains in the XML configuration for compatibility reasons. | No |
HTTP Headers
Format
An HTTP request can contain any number of headers. Headers can be standard-defined, such as Accept
or Content-Type
. They can also be custom. For example, the target application alone knows what they represent. Headers are always a key-value pair. A header name can be reused multiple times which means that a header can have multiple values.
In the HTTP Attribute Connector, headers can have static values or dynamic values. The latter come from a XACML attribute in the request context. In the case of a static value, the <header>
element will contain a <value>
element with the value of the header. In the case of a dynamic value, the <value>
element is replaced with a <headerKey>
element. The <headerKey>
elements are all of type xacmlAttribute
.
Example: Static Header
The following is an example of a header where the value is statically provided.
<header>
<name>customHeader</name>
<value>bar</value>
</header>
Example: Dynamic Header
The following is an example of a header where the value is dynamically provided from a XACML attribute called pip.header
.
<header>
<name>customDynamicHeader</name>
<headerKey>
<xacmlAttribute Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="pip.header" DataType="http://www.w3.org/2001/XMLSchema#string" />
</headerKey>
</header>
Retryable exception
In case no HTTP Response Status Code is returned, an exception is thrown. <retryableException>
allows you to specify which exception(s) should trigger a retry attempt utilizing <retryStrategy>
.
Only exceptions represented by the standard Java java.io.IOException
class or its subclasses such as java.net.SocketException
and java.net.InterruptedIOException
are allowed. For details, check the IOException section of the Java docs.
For example, you can specify that java.net.SocketTimeoutException
which is a network-related exception indicating that a connection attempt timed out, should be retried.
<retryableException typeOfException="java.net.SocketTimeoutException" />
Additionally, you have the option to specify that the exception should be retried only if the message contains the string you provide using the optional flag messageContains
. For example:
<retryableException typeOfException="java.net.SocketTimeoutException" messageContains="Connection timed out" />
Retryable exception caused by HTTP client timeouts
When the configured HTTP client timeout expires, as defined by the system properties in the HTTP client timeouts section, an exception is thrown. If you have specified this exception as retryable, the retry strategy is triggered, and for each retry attempt, the HTTP client timeout limit applies.
More specifically, the AXIOMATICS_HTTP_AC_HTTP_TIMEOUT_SECONDS
parameter sets the duration for each individual retry attempt, while the <maxTimeForRetries>
element described in the in the Retry strategy section defines the maximum total time allowed for all retry attempts combined.
As a result, you can roughly calculate <maxTimeForRetries>
as follows:
<maxTimeForRetries>
= (AXIOMATICS_HTTP_AC_HTTP_TIMEOUT_SECONDS
+ wait times) × (number of retries)
Retry strategy
The retry strategy is triggered by a <retryableHttpCode>
or a <retryableException>
and controls the number, interval, and timeout of retry attempts.
Elements | Description | Mandatory |
---|---|---|
<maxRetries> | The maximum number of times a failed request should be retried. | Yes |
<interval> | The delay between retry attempts. The type of the interval can be either of fixed or exponential type.A fixed interval will wait for the specified millis (ms) before retrying, while an exponential interval will increase the waiting time between retries exponentially by the specified factor after each failure.For example: - <interval millis="500" type="fixed"/> - <interval millis="500" type="exponential" factor="2"/> Tip: An exponential interval helps regulate the frequency of retry attempts by gradually increasing the waiting time between each attempt, mitigating the potential for excessive network and server load due to retry storms. | Yes |
<maxTimeForRetries> | The maximum time allowed for connection attempts, regardless of the number of retries. This is essential to maintain a reasonable response time. Note: This timer initiates upon receiving a request from the authorization engine and tracks the combined duration of the initial connection attempt, any retries, and the transmission of both requests and responses. Note: In OAuth 2.0, the timer applies to both the token retrieval endpoint and the PIP interactions but functions independently for each, essentially creating two separate timers. Important: A retry attempt that starts before the <maxTimeForRetries> expiration is allowed to continue even if it exceeds the <maxTimeForRetries> limit. For example, if the maximum time for retry attempts is set to 3000 ms, and a retry attempt starts at 2700 ms, while the average attempt duration is 500 ms, then it will be allowed to continue even if its completion is achieved after 2700 + 500 = 3200 ms, which exceeds the 3000 ms limit. | No |
Example
<retryableHttpCode>503</retryableHttpCode>
<retryableException typeOfException="java.net.SocketTimeoutException"/>
<retryStrategy>
<maxRetries>4</maxRetries>
<interval millis="300" type="exponential" factor="3"/>
<maxTimeForRetries millis="14000"/>
</retryStrategy>
In this example, the retry strategy allows up to 4 retry attempts with an initial interval of 300 ms. The wait time between subsequent attempts increases exponentially by a factor of 3, and the maximum time allowed for retry attempts is limited to 14000 ms (14 seconds). Additionally, the AXIOMATICS_HTTP_AC_HTTP_TIMEOUT_SECONDS
property is set to 3 seconds.
The following table outlines a possible sequence of interactions between the HTTP Attribute Connector and the PIP, based on the configuration above.
The table serves as a simplified overview and doesn't include the required processing times which may vary.
Attempt | Wait time (ms) | Elapsed time (ms) | Response/exception | Response time (ms) |
---|---|---|---|---|
Initial request | - | 0 | 503 | 500 |
1st retry | 300 | 800 | java.net.SocketTimeoutException | 3000 |
2nd retry | 900 | 4700 | java.net.SocketTimeoutException | 3000 |
3rd retry | 2700 | 10400 | java.net.SocketTimeoutException | 3000 |
4th retry | - | - |
Elapsed time is considered the cumulative duration of the interactions between the HTTP Attribute Connector and the PIP, excluding the time needed for the communication between the PEP and the PDP.
Summary
The information presented in the table indicates that despite limiting the number of retries to four, the 4th retry will not be attempted because after including the 8100 ms wait time, it exceeds the 14000 ms limit.