Integrate with third-party services
The Add-on SDK includes the ability for a custom plugin to integrate with external, third-party services using HTTP.
This section provides a high-level overview of utilizing this functionality from a custom plugin:
Obtaining the HTTP client instance
PingAccess provides access to a HTTP client utility interface, HttpClient, through dependency injection. Plugins are expected to obtain an instance of this interface using an approach like the following.
public class DocumentationPlugin // interfaces and base classes omitted for brevity { private HttpClient httpClient; // ... other code omitted ... @Inject public void setHttpClient(HttpClient httpClient) { this.httpClient = httpClient; } // ... other code omitted ... }
Obtaining a handle to a third-party service
Given a HttpClient instance, a plugin will also need a handle to a third-party service to make an outbound HTTP call to the service represented by the Third-Party Service administrative configuration object. This handle is an instance of the ThirdPartyServiceModel class and is specified to the HttpClient in its send method.
There are two different ways to obtain a ThirdPartyServiceModel instance:
Administrator-configured third-party services
The PingAccess Administrative UI and application programming interface (API) allow administrators to define the communication configuration for an external service by defining a third-party service. These configuration objects can then be associated with custom plugins through their configuration.
To enable a plugin’s configuration to reference a third-party service, it should define a field in the configuration with the type of ThirdPartyServiceModel.
private static class Configuration extends SimplePluginConfiguration { // ... other code omitted ... @UIElement(order = 30, type = ConfigurationType.SELECT, label = "Risk Authorization Service", modelAccessor = ThirdPartyServiceAccessor.class, required = true) @NotNull private ThirdPartyServiceModel riskAuthzService; // ... other code omitted ... public ThirdPartyServiceModel getRiskAuthzService() { return riskAuthzService; } public void setRiskAuthzService(ThirdPartyServiceModel riskAuthzService) { this.riskAuthzService = riskAuthzService; } }
The important items in this example:
-
The
modelAccessor
attribute of the UIElement must be set toThirdPartyServiceAccessor
. -
The field in the plugin configuration class must be of type
ThirdPartyServiceModel
.
Third-party services for the OAuth authorization server and OIDC provider
In addition to providing a way for an administrator to configure a plugin to use an arbitrary third-party service, PingAccess allows a plugin to use a third-party service that represents the OAuth Authorization Server or OpenID Connect (OIDC) provider. The benefit of leveraging this functionality is that a plugin can require access to either of these services without requiring the administrator to configure the plugin to use those services.
Similar to the previous section, the plugin obtains a ThirdPartyServiceModel instance that is a handle to the OAuth Authorization Server or OIDC provider by indicating this requirement in its plugin configuration class. However, the mechanism is a bit different, as shown in the following example.
private static class Configuration extends SimplePluginConfiguration { // ... other code omitted ... private ThirdPartyServiceModel oidcProvider; // ... other code omitted ... public ThirdPartyServiceModel getOidcProvider() { return oidcProvider; } @Inject @OidcProvider public void setOidcProvider(ThirdPartyServiceModel oidcProvider) { this.oidcProvider = oidcProvider; } }
The setter for the oidcProvider field is annotated with the @OidcProvider
annotation.
If the @OidcProvider
annotation includes a parameter, that parameter specifies a required endpoint defined by the OIDC provider metadata of the current token provider. When the plugin is instantiated, the validation for the @OidcProvider
parameter will pass only if the specified endpoint is a valid HTTP Uniform Resource Identifier (URI) in the OIDC provider metadata. For example, the following annotation will require the backchannel_authentication
URI.
@OidcProvider(“backchannel_authentication”)
Making a HTTP call to a third-party service
With an instance of HttpClient and an instance of ThirdPartyServiceModel in hand, a plugin can make a HTTP call to the external service represented by the ThirdPartyServiceModel. Here is an example method that makes a GET request to a resource on the external service with a path of /data
and a query string of page=1
.
private static CompletionStage<ClientResponse> sendRequest(HttpClient httpClient, ThirdPartyServiceModel model) { Headers headers = ClientRequest.createHeaders(); headers.setAccept(Collections.singletonList("application/json")); ClientRequest request = new ClientRequest(Method.GET, "/data?page=1", headers); return httpClient.send(request, model); }
The result of the HttpClient send
method is a CompletionStage. A CompletionStage is returned because PingAccess is performing the HTTP call asynchronously and as a result, handling of the result of the call needs to be performed by callbacks registered with the CompletionStage.
You can use the getRequestUri()
method to stand in for the endpoint. This can be useful if the endpoint is not known during development.
ClientRequest request = new ClientRequest(Method.GET, model.getRequestUri().get(), headers);
The RequestUri
is set by the @OidcProvider("RequestUri")
annotation, and is unset if the @OidcProvider("RequestUri")
annotation is not present.
For a more complete example of using the HttpClient to make an external HTTP call, see the sample SDK plugins packaged with the PingAccess distribution.
Base classes
The SDK provides the following base classes to make it easier to implement a plugin that leverages the HttpClient interface. They all provide access to a HttpClient instance using a getHttpClient method:
-
AsyncRuleInterceptorBase
-
AsyncSiteAuthenticatorInterceptorBase
-
AsyncIdentityMappingPluginBase
-
AsyncLoadBalancingPluginBase
Sample plugins
The use of the HttpClient and ThirdPartyServiceModel classes are demonstrated in the following samples provided in the PingAccess distribution:
- RiskAuthorizationRule
-
A rule that obtains a risk score from an external, risk service as well as leveraging the OAuth authorization server to obtain an OAuth access token used to access the risk service.
- MetricBasedPlugin
-
A load balancing strategy that obtains host capacity metadata from an external service.