When upgrading PingAccess, review the changes made to thePingAccess add-on SDK for Java, analyze your addons, and make any necessary changes to ensure continued compatibility.
The following sections provide a detailed description of the changes, organized by package. Where relevant, code examples show you how to port existing code to account for the changes in the SDK APIs.
Prevent modification to request in response chain
Starting in PingAccess 6.1, any modifications made to a request or its header fields during response processing will now result in a warning log message and the modification operation being ignored. Previously, PingAccess would log a warning message about the modification but still allow the modification operation to complete.
Retrieving key pair and trusted certificate group configuration data
In the previous version of the SDK, a SDK plugin accessed the configuration data of a key pair or trusted certificate group configured using the administrative API by annotating a field in the plugin's PluginConfiguration class with a JsonDeserialize annotation, specifying the appropriate custom deserializer from the SDK.
public class Configuration extends SimplePluginConfiguration
{
@JsonDeserialize(using = PrivateKeyDeserializer.class)
KeyStore.PrivateKeyEntry keyPair;
@JsonDeserialize(using = TrustedCertificateGroupDeserializer.class)
Collection<X509Certificate> certificateGroup;
}
In the current version of the SDK, this mechanism has changed to be less error-prone as well as to provide access to more properties of the key pairs and trusted certificate groups. The previous configuration class should be ported to the following:
public class Configuration extends SimplePluginConfiguration
{
KeyPairModel keyPair;
TrustedCertificateGroupModel certificateGroup;
}
The KeyPairModel#getPrivateKeyEntry
method provides access to the
KeyStore.PrivateKeyEntry
object for the corresponding key pair
in the administrative configuration. The
TrustedCertificateGroupModel#getCertificates
method provides
access to the Collection of X509Certificate objects in the corresponding trusted
certificate group in the administrative configuration. Refer to the JavaDoc for each
of these classes for more information.
- Before PingAccess 5.0:
-
import com.pingidentity.pa.sdk.accessor.PrivateKeyAccessor; import com.pingidentity.pa.sdk.accessor.TrustedCertificateGroupAccessor; // … class definition omitted ... private void invokePrivateKeyAccessorGet( PrivateKeyAccessor accessor, String id) { KeyStore.PrivateKeyEntry keyPair = accessor.get(id); } private void invokeTrustedCertificateGroupAccessorGet( TrustedCertificateGroupAccessor accessor, String id) { Collection<X509Certificate> certificates = accessor.get(id); }
- After PingAccess 5.0:
-
import com.pingidentity.pa.sdk.accessor.certgroup.TrustedCertificateGroupModel; import com.pingidentity.pa.sdk.accessor.keypair.KeyPairAccessor; // … class definition omitted ... private void invokePrivateKeyAccessorGet( KeyPairAccessor accessor, String id) { KeyStore.PrivateKeyEntry keyPair = accessor.get(id) .map(KeyPairModel::getPrivateKeyEntry) .orElse(null); } private void invokeTrustedCertificateGroupAccessorGet( TrustedCertificateGroupAccessor accessor, String id) { Collection<X509Certificate> certificates = accessor.get(id) .map(TrustedCertificateGroupModel::getCertificates) .orElse(null); }
Changes to validation of PluginConfiguration instances
In the previous version of the SDK, the ConfigurablePlugin#configure method was invoked and passed a PluginConfiguration instance. The ConfigurablePlugin was expected to assign the specified PluginConfiguration instance to a field annotated with the javax.validation.Valid annotation. After the configure method returned, PingAccess passed the ConfigurablePlugin instance to a javax.validation.Validator for further validation.
If setup correctly, this logic allows javax.validation.Constraint annotations to declare the validation to be applied to fields in a PluginConfiguration implementation, ensuring the configuration is valid as well as providing validation error message to PingAccess to provide to administrators using the Administrative API or UI.
However, if the ConfigurablePlugin#configure method needed to post-process the specified PluginConfiguration instance, the method needed to duplicate all the validation declared on the fields of the PluginConfiguration.
To remove the need for this duplication of validation logic, PingAccess now validates the PluginConfiguration instance with a javax.validation.Validator prior to passing the instance to the ConfigurablePlugin#configure method.
Further, the ConfigurablePlugin no longer needs to annotate the field used to hold the PluginConfiguration instance. The field is still necessary to implement the ConfigurablePlugin#getConfiguration method.
The following example ConfigurablePlugin implementation demonstrates this change.
public class ValidationExample
implements ConfigurablePlugin<ValidationExample.Configuration>
{
// @Valid annotation no longer required
private Configuration configuration;
@Override
public void configure(Configuration configuration) throws ValidationException
{
this.configuration = configuration;
// With the previous version of the SDK, these assertions were not
// guaranteed to be true, despite the javax.validation.Constraint
// annotations enforcing these conditions.
//
// In the current version of the SDK, these assertions are guaranteed
// to be true because they are enforced by the javax.validation.Constraint
// annotations on the fields in the PluginConfiguration class, and the
// PluginConfiguration validation is performed before invoking the
// configure method.
//
// The end result is that plugins can remove duplicated validation
// logic from the configure method if further post-processing of the
// configuration needs to be performed.
assert(configuration.getAttributeName() != null);
assert(configuration.getAttributeName().length() > 0);
assert(configuration.getAttributeName().length() <= 16);
assert(configuration.getAttributeValue() != null);
}
@Override
public Configuration getConfiguration()
{
return configuration;
}
static class Configuration extends SimplePluginConfiguration
{
@NotNull
@Size(min = 1,
max = 16,
message = "Attribute name length must be between 1 and 16 characters")
private String attributeName;
@NotNull
private String attributeValue;
public String getAttributeName()
{
return attributeName;
}
public void setAttributeName(String attributeName)
{
this.attributeName = attributeName;
}
public String getAttributeValue()
{
return attributeValue;
}
public void setAttributeValue(String attributeValue)
{
this.attributeValue = attributeValue;
}
}
}