Connection section
The connection section contains all the information required to contact a remote service. More specifically, the <connection> element contains the following nested elements:
| 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 in the URL section. | Yes |
<keystore> | Contains a private key and its associated certificate, specifically for mutual TLS client authentication. Read the Keystore and truststore section for details. | No |
<truststore> | A keystore that contains certificates that the attribute connector will trust. Read the Keystore and truststore section for details. | No |
<connectionKey> | Specifies an XACML attribute that provides the required value to replace a placeholder in a parameterized URL. See the URL section for details. | 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, refer to the HTTP headers section of MDN web docsOpens in a new tab . | No |
<method> | The HTTP request method (GET or POST) for the request. The default is POST. Note: The value is case-insensitive. | No |
<authentication> | Specifies the authentication method that the attribute connector will use to authenticate itself with the HTTP server. Read the authentication section for details. | No |
<acceptedHttpCode> | Besides the standard successful code 200, this option lets you define an additional HTTP response code that will be treated as successful.The attribute connector will return the body of any HTTP response with an accepted status code. Otherwise, it will fail unless the unaccepted code is specified using the <ignoredHttpCode> element below, in which case it will be ignored.Note: There can be several instances of this element. | No |
<ignoredHttpCode> | Specifies an HTTP response code that, while not considered successful, should be ignored and not treated as an error. Normally, when the attribute connector encounters an unsuccessful response code, it reports an error. However, if the specific code is specified as ignored, it will instead return an empty value for the associated attribute, instead of returning an error. Note: There can be several instances of this element. | No |
<retryableHttpCode> | Specifies an HTTP response 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 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 attributes:
insecure:This attribute indicates whether TLS certificates received from the server are validated or not, when using a secure connection (HTTPS). The default value is
false.ImportantEnabling this attribute poses a security risk and is strictly prohibited in production environments. Its intended use is solely for troubleshooting in development environments. If activated, the attribute connector will issue a warning as a reminder of the security implications.
useWindowsAuthentication:Indicates whether the connector will use proprietary Windows authentication when connecting to a Microsoft Windows server. When enabled, this feature is normally used along with the
NTLMauthentication mode setting in the<authentication>configuration section.noteThis attribute is deprecated and remains in the XML configuration for compatibility reasons. Ιf set to
truean error will be thrown.
URL
URLs can be static or dynamic. Static URLs remain constant for all attribute connector requests. Conversely, dynamic URLs incorporate parts derived from other XACML attributes, making them adaptable, especially for REST calls where the URL is typically parameterized.
Static URL
Let’s take for instance a REST call to an API which provides information about users such as 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>
Dynamic URL
Creating a parameterized URL involves defining placeholders within the URL using curly braces ({ and }). Inside these braces, place a number representing the key's index, starting from 0.
Indexes can be used multiple times within the URL.
It's crucial to ensure you have the same number of connectionKey elements as unique key indexes. Each connectionKey element should be of type xacmlAttribute.
The example below has a URL with a single dynamic part, {0}, at the end. The attribute connector replaces this part with values from the example.userId XACML attribute.
<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>
Keystore and truststore
Keystores and truststores contain certificates and private keys that are used by the attribute connector to securely communicate with the external HTTP server.
More specifically, a keystore stores private keys or certificates with public keys that are used to prove the message integrity and sender identity.
On the other hand, a truststore holds onto certificates that the attribute connector will trust. This is only required if your HTTP server has a certificate which is not in Java’s or the operating system’s truststore already.
Both elements have the following attributes:
fileThe filename, optionally including its relative path. For example,
/path/to/keystores/keystore.jks.typeSpecifies the keystore/truststore type, determining the entries it can store. Valid options are
JCEKS,JKS,DKS,PKCS12, andPKCS11. The default isJKSand will be used if no value is provided.passwordThe password required to access the keystore/truststore file. The default is
changeitand will be used if no value is provided.
Authentication
The HTTP Attribute Connector simplifies HTTP request authentication with three methods: Basic authentication, Bearer authentication, and OAuth 2.0/OIDC. Once you choose an authentication mode, the connector automatically generates the necessary HTTP authentication headers, eliminating the need for manual configuration using the header element. For complex authentication modes, the connector retrieves access tokens from external identity providers seamlessly.
Specify the desired authentication mode using the authenticationMode attribute. Valid values are Basic, Bearer, or OAuth2. Each mode requires its own configuration details, as outlined 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.
Details
The <authentication> element can have the following attributes:
authenticationModeThis attribute is mandatory and the supported values are
Basic,Bearer, andOAuth2(case-sensitive).noteNLTMmode was also supported in the past, however this is no longer the case. Using it will result in an error.tokenServiceAuthenticationModeThis optional attribute affects only OAuth 2.0 authentication. It specifies how client credentials (
clientIdandclientSecret) are sent when requesting an access token. There are two supported values (case-sensitive):Basic: In this mode, credentials are sent in a request header following Basic Authentication rules.Form: In this mode, credentials are included as form fields within the request body.
If not specified, the default is
Basic.
The authentication subsection also includes the following nested elements:
| Element | Description | Mandatory |
|---|---|---|
<tokenUrl> | This element is mandatory when the authentication mode is set to OAuth2 and must specify the URL of the endpoint where an access token can be retrieved.In this mode, the connector automatically manages the access token retrieval process. It uses the application identifier ( clientId), secret (clientSecret), and optionally the desired access scope (scope) to obtain the token.Additionally, the connector automatically sets the appropriate HTTP authentication header based on the retrieved token, so you don't need to manually specify it using the 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 and should contain a security token. In this mode, the appropriate HTTP authentication headers will be automatically created, meaning that it doesn't need to be specified manually using the 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 with password, are required for the Basic authentication mode. In this mode, the appropriate HTTP authentication headers will be automatically created, meaning that it doesn't need to be specified manually using the header element. | 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, meaning that it doesn't need to be specified manually using the header element. | 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 |
Basic authentication
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.
Bearer authentication
The following example shows how to configure the HTTP requests to use Bearer token:
<authentication authenticationMode="Bearer">
<token>secret-token</token>
</authentication>
<token>: a string representing a Bearer token.
OAuth 2.0 or OpenID Connect (OIDC)
The following example shows how to configure the HTTP requests to use OAuth 2.0 or OpenID Connect (OIDC):
<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, access tokens are retrieved by sending application credentials in the HTTP headers. However, some identity providers require credentials to be sent in the request body instead. In such cases, you can use the tokenServiceAuthenticationMode attribute 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 OAuth 2.0 access token toForm. This attribute is optional, and its default value isBasic.
HTTP headers
Format
HTTP requests can include multiple headers, either standard ones like Accept or Content-Type, or custom ones defined by the target application. Each header is a key-value pair, and while the key name can be repeated, each key can only have a single value.
When using the HTTP Attribute Connector, headers can have static values that are explicitly defined, or dynamic values based on XACML attributes in the request context:
- For static values, the
<header>element contains a<value>element with the actual header value. - For dynamic values, the
<value>element is replaced with a<headerKey>element referencing the relevant XACML attribute. All<headerKey>elements have the typexacmlAttribute.
Static header
The following is an example of a header where the value is statically provided.
<header>
<name>customHeader</name>
<value>bar</value>
</header>
Dynamic header
The following is an example of a header where the value is dynamically retrieved from an 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.