
OAuth Customization using Plugins
On this page
OAuth secured applications can be developed in your preferred technologies, and they then interact with the identity and access management (IAM) system using HTTPS requests. You only need to deploy the IAM system, then point your apps to its endpoints. For the Curity Identity Server, deployment is typically managed by running Docker containers:
docker run -it -e PASSWORD=<ADMIN_PASSWORD> -p 6749:6749 -p 8443:8443 curity.azurecr.io/curity/idsvr
You should never need to build the code for the IAM system or be an expert in its underlying technology. OAuth is a framework though, and at times you need to take closer control over behavior. Extensibility may be needed in some areas, so that you avoid being blocked when implementing security solutions.
Area | Description |
---|---|
Look and Feel | Control over the login branding, appearance and layout |
Authentication | Customizing authentication or implementing a new authentication method |
Actions | Using and linking user attributes during or after authentication |
User Data | Storing custom user attributes in the authorization server |
Data Sources | Interacting with custom data sources and credential stores |
Token Issuing | Controlling the format and algorithms used during token issuing |
API Claims | Returning custom information to APIs in JWT access tokens |
Operational | Being notified of runtime events that occur in the authorization server |
The cleanest way to manage this type of customization is to do so within the IAM system, rather than coding complex workarounds at the application level.
Managing Extensibility
There are three main levels for customizing the Curity Identity Server, from enhancing the look and feel, to writing scripts, to implementing Java plugins.
Look and Feel
Companies often want an early focus on login branding, to customize the Look and Feel. In the Curity Identity Server this can be done in a basic way using the Admin UI, or more detailed HTML customizations can be made via the UI Builder. This typically involves only changes to CSS assets.
Scripting
Later on, to control authentication and token issuing, Scripting is used. This requires code, but it is implemented with only simple JavaScript procedures. The scripted logic can also interact with infrastructure, such as sending custom HTTP requests or connecting to data sources.
Plugins
Scripting has some limitations though, especially for more complex tasks. When you want to take closer control over behavior, such as building a completely custom authentication method, the Plugin SDK is the preferred option. This requires you to write Java or Kotlin code, using SDK objects and interfaces.
Development Setup
Many developers are not Java coders, and instead build their user facing apps and APIs in other technology stacks, such as Node.js, Python or C#. There may be concerns about how to manage setup and deployment aspects, so this tutorial shows how to quickly overcome these challenges, and provides some useful links. The only thing left to do in order to implement a plugin will be to write the Java or Kotlin code, which any skilled developer will soon learn.
Plugin Resources
When getting started with plugins, first watch these two introductory videos, then browse the developer documentation:
- Developing a Plugin Part 1
- Developing a Plugin Part 2
- Plugin Development Overview
- Plugin SDK Documentation
Plugin Types
To understand more about plugin coding, see the Curity code examples, which cover the following plugin categories. There are many links to GitHub repositories, from which you can borrow coding techniques for your own plugins:
- Alarm Handlers
- Authenticators
- Authentication Actions
- Data Access
- Claims Providers
- Consentors
- Emailers
- Event Listeners
- SMS Senders
- Authorization Managers
Install Prerequisites
Next ensure that these tools are installed:
- A Java Development Kit (JDK), such as those provided by Azul
- The maven build tool
- An integrated development environment (IDE), such as IntelliJ Community Edition
The Curity Identity Server stays current with the latest long term support (LTS) version of Java, and it is recommended to use an up to date version such as JDK 17, so that developers can write plugins with productive modern code. See the Java Version Details for further information.
Create a Project
A common type of plugin is a new authenticator, since various third party providers offer an authentication API that is not quite OpenID Connect compliant. To get started building one, run the following command, which uses Maven Archetypes to create Java project files for a custom authenticator:
mvn -B archetype:generate \-DarchetypeArtifactId=identityserver.plugins.archetypes.authenticator \-DarchetypeGroupId=io.curity \-DarchetypeVersion=3.0.0 \-DartifactId=example-authenticator \-DgroupId=com.mycompany.plugins.exampleauthenticator \-DpluginName=Example \-Dversion=1.0.0-SNAPSHOT
If you prefer to develop your plugin in Kotlin, run the following command instead:
mvn -B archetype:generate \-DarchetypeArtifactId=identityserver.plugins.archetypes.kotlin-authenticator \-DarchetypeGroupId=io.curity \-DarchetypeVersion=3.0.0 \-DartifactId=example-authenticator \-DgroupId=com.mycompany.plugins.exampleauthenticator \-DpluginName=Example \-Dversion=1.0.0-SNAPSHOT
Getting Started Coding
If you open the generated folder in an IDE, you will see the core Java files, and the main development job is to implement a handler class:

The archetypes provide a skeleton implementation that is injected with its configuration and also some example SDK objects.
public final class ExampleAuthenticatorRequestHandler implements AuthenticatorRequestHandler<RequestModel>{private static final Logger _logger = LoggerFactory.getLogger(ExampleAuthenticatorRequestHandler.class);private final ExampleAuthenticatorPluginConfig _config;private final AuthenticatorInformationProvider _authInfoProvider;private final ExceptionFactory _exceptionFactory;public ExampleAuthenticatorRequestHandler(ExampleAuthenticatorPluginConfig config,ExceptionFactory exceptionFactory,AuthenticatorInformationProvider authInfoProvider){_config = config;_exceptionFactory = exceptionFactory;_authInfoProvider = authInfoProvider;}@Overridepublic Optional<AuthenticationResult> get(RequestModel requestModel, Response response){_logger.info("GET request received for authentication authentication");return Optional.empty();}
Example Authenticator
This tutorial will implement a stub authenticator that signs you in with a fixed mock user. This is not a useful real world scenario of course, but provides a starting point for your own logic. It also highlights that there are no limits to the type of authentication you can implement with plugins.
Input Configuration
The plugin will first require the following field to be populated in the Admin UI:
public interface ExampleAuthenticatorPluginConfig extends Configuration{@DefaultString("mockuser")@Description("A fixed string to represent a mock user")String getMockUser();}
Implement Plugin Code
To implement a real plugin, the most common approach is to start by finding something similar in the Curity GitHub repositories. Searching for topic:authenticator
would find some plugins that implement custom authentication:

For this tutorial, simply replace the request handler class with the following Java code:
public final class ExampleAuthenticatorRequestHandler implements AuthenticatorRequestHandler<RequestModel>{private static final Logger _logger = LoggerFactory.getLogger(ExampleAuthenticatorRequestHandler.class);private final ExampleAuthenticatorPluginConfig _config;public ExampleAuthenticatorRequestHandler(ExampleAuthenticatorPluginConfig config){_config = config;}@Overridepublic RequestModel preProcess(Request request, Response response){response.setResponseModel(templateResponseModel(emptyMap(),"authenticate/get"), NOT_FAILURE);return new RequestModel(request);}@Overridepublic Optional<AuthenticationResult> get(RequestModel requestModel, Response response){return Optional.empty();}@Overridepublic Optional<AuthenticationResult> post(RequestModel requestModel, Response response){var user = _config.getMockUser();_logger.debug("Successfully authenticated for user: {}", user);return Optional.of(new AuthenticationResult(user));}}
A trivial HTML template will also be used, so create a directory tree and a file called get.vm
, at this path, under the resources folder:
/templates/authenticator/example/authenticate/get.vm
Then paste in the following template, which contains a simple custom HTML body. This also uses styles shipped with the Curity Identity Server. For a real plugin it is recommended to use localizable message files instead of the hard coded text used here:
#define ($_body)<h2>Example Authenticator</h2><form method="post"><button type="submit" class="button button-fullwidth button-primary">Authenticate</button></form>#end#parse("layouts/default")
Add a Library Dependency
The example plugin is trivial, but for a more real world one you will often need to use additional Java libraries. Your plugin can use Server Provided Dependencies but others must be deployed. For this tutorial, edit the pom.xml
file and add one, such as this JSON serialization library:
<dependencies><dependency><groupId>se.curity.identityserver</groupId><artifactId>identityserver.sdk</artifactId><version>${project.curityVersion}</version><scope>provided</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${project.slf4jVersion}</version><scope>provided</scope></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>${project.gsonVersion}</version></dependency></dependencies>
Deploy and Test the Plugin
Before adding much plugin code, you will want to get an end-to-end setup working, so that you can build, deploy, and interactively test the plugin.
Build to JAR Files
In order to compile code to JAR files and also deal with third party dependencies, you will need to add some plugins to the build setup. If you are using third party libraries, include the maven dependency plugin:
<build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.10.1</version><configuration><source>17</source><target>17</target></configuration></plugin><plugin><artifactId>maven-dependency-plugin</artifactId><executions><execution><phase>process-sources</phase><goals><goal>copy-dependencies</goal></goals><configuration><includeScope>compile</includeScope><outputDirectory>${project.build.directory}</outputDirectory></configuration></execution></executions></plugin></plugins></build>
You can then run the following command line to build a JAR file containing the plugin's compiled code and resources:
mvn package
For the example authenticator, the following files are built to the target
folder and will need to be deployed:
example-authenticator-1.0.0-SNAPSHOT.jargson-2.9.0.jar
Deploy the Plugin
The JAR files must then be deployed with instances of the Curity Identity Server, to a subfolder of usr/share/plugins
. The following docker compose example shows the use of paths under the plugins
root folder:
version: '3.8'services:curity-idsvr:image: curity.azurecr.io/curity/idsvr:latestports:- 6749:6749- 8443:8443volumes:- ./example-authenticator-1.0.0-SNAPSHOT.jar:/opt/idsvr/usr/share/plugins/example-authenticator/example-authenticator-1.0.0-SNAPSHOT.jar- ./gson-2.9.0.jar:/opt/idsvr/usr/share/plugins/example-authenticator/gson-2.9.0.jar
Create a Plugin Instance
Once the Curity Identity Server and plugin are deployed, you can create an instance of the plugin using the Admin UI, and enter its required input values. The example authenticator is shown below, and it can be used by one or more OAuth client applications.

Developer Testing
You will need to register a test client that uses the custom authenticator, as described in the Getting Started guides. Using OAuth Tools can be a productive way to test your plugin against a locally deployed instance of the Curity Identity Server:

Running the Plugin
Once you have a test client, you can run a code flow, to perform a user login. This will present the minimal HTML template created earlier. Clicking Authenticate
will then cause the post
method of the example authenticator to be called.

Authentication then completes, and control is returned to the test client, after which the application can redeem an authorization code for a set of tokens.
View Logs
To troubleshoot issues during development you will add log messages to the plugin, which are then included in the Curity Identity Server logs. Use the 'DEBUG' or INFO
log levels during development. Ensure that any sensitive information, such as the username shown here, is then removed from logs.
local-curity-idsvr-1 | 2022-09-26T10:09:21:512+0000 DEBUG GgKats8Z 325ba718 {req-132} com.mycompany.plugins.exampleauthenticator.authentication.ExampleAuthenticatorRequestHandler - Successfully authenticated for user: mockuser
Debugging
It is also possible to debug your plugin's code, while it is running in a Docker deployed instance of the Curity Identity Server. The Attach a Debugger tutorial explains how to do this.
Techniques
This section links to further information for techniques that could be applied to multiple use cases. Once understood, it will also be possible to apply them to your own scenarios.
Custom Authentication Redirects
Most commonly the Curity Identity Server connects to external identity providers using OpenID Connect or SAML. In some cases custom code is needed and these examples show how to initiate them and handle callbacks:
Plugin | Description |
---|---|
Redirect Action | Redirect to a custom application, sending the subject claim and receiving back custom data |
Slack Authenticator | A custom authenticator that uses a third party authentication API |
Custom User Input
The Username Password Authenticator has a branch that shows how to capture custom data during authentication. This is done by adding the field to the RequestModel
for an existing screen.
Custom Templates
Both bespoke HTML forms and emails can be implemented, and this is done using velocity templates, to allow custom data to be processed on the server. The following examples show how to create custom templates.
Plugin | Description |
---|---|
Username Password Authenticator | Contains multiple custom forms and also uses custom email templates |
Send Email Action | Shows how to do bespoke sending of emails, which can also use custom templates |
The Username Password Authenticator shows how to use and validate view models using Java annotations. Validation can fail either because the annotations are not satisfied or because deeper checks fail. In these cases the form needs to present error messages and avoid losing the user's input.
Custom User Creation
The following plugins show how to make HTTP requests to external systems. In both cases a remote user is created after authentication, and this responsibility is best implemented as an authentication action.
Plugin | Description |
---|---|
Kong Dev Portal User Provisioner | Uses an HTTP client managed by the Curity Identity Server |
Azure API Management User Provisioner | Uses an HTTP client from the Azure SDK |
Custom Claims
Claims issued in tokens can be customized with information from third party systems, by implementing a ClaimsProvider
. The Salesforce Claims Provider shows how to make a more complex external connection that requires a JWT credential. This plugin also demonstrates the use of caching and Managed Objects.
Custom Data Sources
The Curity Identity Server can connect to many types of data source and provides interfaces for operating on data. The following examples can be used as a guide when integrating with custom data sources directly.
Plugin | Description |
---|---|
Custom Credential Validator | Custom validation of password credentials to support any cryptographic hash algorithm |
MongoDB Data Source | Shows how to implement various interfaces to connect to NoSQL data sources |
Custom Auditing
Auditing can be output to a JDBC data source, though it is also possible to capture events programmatically. The Amazon SQL Event Listener provides an example of receiving audit data, then sending it to a queue. Various subscribers could then use the data.
Conclusion
The plugin SDK for the Curity Identity Server gives you powerful control over core behavior, and you do not need to be a Java expert to use it. A simplified programming model is provided, and this page explained the main steps, with links to further information. This will enable you to customize security related behavior during OAuth flows, in a technically simple and standard manner.
Join our Newsletter
Get the latest on identity management, API Security and authentication straight to your inbox.
Start Free Trial
Try the Curity Identity Server for Free. Get up and running in 10 minutes.
Start Free Trial