---
title: "Example plugin: password credential validator"
description: The password-credential-validator is one of the simplest plugin types, so it's a good place to learn the structure and process of building a plugin for PingFederate. A password-credential-validator validates a username/password pair and optionally supports password change, reset, and username recovery.
component: pingfederate
version: 13.1
page_id: pingfederate:sdk_developers_guide:pf_example_plugin_password_credential_validator
canonical_url: https://docs.pingidentity.com/pingfederate/13.1/sdk_developers_guide/pf_example_plugin_password_credential_validator.html
llms_txt: https://docs.pingidentity.com/pingfederate/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
section_ids:
  the-maven-project: The Maven project
  the-plugin-class: The plugin class
  the-gui-descriptor-and-attribute-contract: The GUI descriptor and attribute contract
  optional-interfaces: Optional interfaces
  the-deployment-descriptor: The deployment descriptor
  deploy: Deploy
  result: Result
---

# Example plugin: password credential validator

The `password-credential-validator` is one of the simplest plugin types, so it's a good place to learn the structure and process of building a plugin for PingFederate. A `password-credential-validator` validates a username/password pair and optionally supports password change, reset, and username recovery.

All files for this example plugin are located in the `<pingfed-install>/pingfederate/sdk/examples/password-credential-validator` directory.

## The Maven project

`pingfederate-sdk` is declared as `provided`, so it's in the compile classpath, but never bundled into your jar.

1. Open the `pom.xml` file in a text editor.

2. Add the `PingIdentityMaven` repository so the dependency can be resolved:

   ```xml
   <repositories>
       <repository>
           <releases>
               <enabled>true</enabled>
               <updatePolicy>always</updatePolicy>
               <checksumPolicy>warn</checksumPolicy>
           </releases>
           <id>PingIdentityMaven</id>
           <name>PingIdentity Release</name>
           <url>http://maven.pingidentity.com/release/</url>
           <layout>default</layout>
       </repository>
   </repositories>
   ```

3. Save and close `pom.xml`.

4. Open a terminal window, navigate to the `<pingfed-install>/pingfederate/sdk/examples/password-credential-validator` directory, and run `mvn clean install` to build the plugin.

## The plugin class

The `SamplePasswordCredentialValidator` class implements the `PasswordCredentialValidator` class. It also implements three optional interfaces to pick up extra capabilities:

* `ChangeablePasswordCredential`

* `ResettablePasswordCredential`

* `RecoverableUsername`

Regardless of which interfaces you implement, two methods are always required:

* `configure(<Configuration>, <configuration>)`: PingFederate calls this once per instance, right after creating it. Settings are made in the admin console and passed to your plugin. Read what you need into instance fields here. PingFederate manages concurrency automatically. Nothing touches your plugin instance until `configure()` finishes.

* `getPluginDescriptor()`: Describes the plugin back to PingFederate. Learn more in the next section.

The actual work happens in the interface's core method, `processPasswordCredential(username, password)`, which returns an `AttributeMap` describing the authenticated user on success, or `null` if the credentials don't match.

## The GUI descriptor and attribute contract

Complete the following inside the `getPluginDescriptor()` class:

1. Build a class for each admin-configurable field, such as `TextFieldDescriptor` or `CheckBoxFieldDescriptor`.

   1. Attach a validator like `RequiredFieldValidator` where a value is mandatory.

   2. Add each field to a `GuiConfigDescriptor`.

2. Wrap that class in a new `PluginDescriptor(<TYPE>, this, guiDescriptor)` where \<TYPE> is the display name admins will see in the console.

3. Call `setAttributesContractSet()` with the attribute names your plugin guarantees to populate. In this case, the attributes are `username`, `givenName`, and `mail`.

## Optional interfaces

Each optional interface you implement unlocks a capability for the admin console to surface conditionally:

| Optional Interface               | Capabilities                                                                                                              |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `ChangablePasswordCredential()`  | * `changePassword()`

* `isPasswordChangeable()`

* `isChangePasswordEmailNotifiable()`

* `isPasswordExpiryNotifiable()` |
| `ResettablePasswordCredential()` | - `findUser()`

- `resetPassword()`

- `isPasswordResettable()`                                                           |
| `RecoverableUserName()`          | * `findUserByMail()`

* Also a few attribute-name getters                                                                 |

Skip any of these interfaces your plugin doesn't support. A bare-minimum password credential validator only needs `PasswordCredentialValidator`.

## The deployment descriptor

The deployment descriptor is a static file that PingFederate automatically reads from your jar that specifies two things:

* What type of plugins are available in this jar.

* What implementation class names to load as an available plugin.

The descriptor file is located at `<pingfed-install>/pingfederate/sdk/examples/password-credential-validator/src/main/resources/PF-INF/<descriptor-name>`.

The contents of that file are simply the fully-qualified name of your implementing class:

```none
com.pingidentity.password.credential.validator.SamplePasswordCredentialValidator
```

So for each type of plugin you create, add an appropriate text file to the `PF-INF` directory.

The following table contains the interface and descriptor filename for each example plugin bundled with PingFederate:

| Plugin type                    | Interface                         | Descriptor file name              |
| ------------------------------ | --------------------------------- | --------------------------------- |
| Authentication Selector        | `AuthenticationSelector`          | `authentication-selectors`        |
| Authorization Detail Processor | `AuthorizationDetailProcessor`    | `authorization-detail-processors` |
| Risk Provider                  | `CaptchaProvider`                 | `captcha-providers`               |
| Dynamic Client Registration    | `DynamicClientRegistrationPlugin` | `dynamic-client-registration`     |
| Identity Store Provisioner     | `IdentityStoreProvisioner`        | `identity-store-provisioners`     |
| IdP Authentication Adapter     | `IdpAuthenticationAdapterV2`      | `idp-adapters`                    |
| Notification Publisher         | `NotificationPublisher`           | `notification-sender`             |
| Out-of-Band Auth Plugin        | `OOBAuthPlugin`                   | `oob-auth-plugins`                |
| Password Credential Validator  | `PasswordCredentialValidator`     | `password-credential-validators`  |
| Secret Manager                 | `SecretManager`                   | `secret-manager`                  |
| SP Authentication Adapter      | `SpAuthenticationAdapter`         | `sp-adapters`                     |
| Token Generator                | `TokeGenerator`                   | `token-generators`                |
| Token Processor                | `TokenProcessor`                  | `token-processors`                |

Update the descriptor manually when you add, rename, or remove a plugin class. If your jar implements multiple plugin classes of the same type list each on its own line.

## Deploy

1. Copy the `target/password-credential-validator-example.jar` file.

2. Paste it to `<pingfed-install>/pingfederate/server/default/deploy`.

3. Restart PingFederate.

## Result

Your plugin appears as `Sample Password Credential Validator`, which is the \<TYPE> string you entered under GUI descriptor and attribute contract, wherever password credential validators can be selected in the admin console.
