Skip to content
  • SDKs and APIs
  • Back end SDKs

Java SDK

The Kinde Java SDK allows developers to connect their Java app to Kinde.

You can find our Java SDK and Java starter kit in GitHub.

The SDK is officially only supported for Java version 17 or later.

Register with Kinde

Link to this section

If you haven’t already created a Kinde account, register for free here. Registration gives you a Kinde domain, which you will need to get started. e.g. yourapp.kinde.com.

Kinde Java core

Link to this section

The Kinde Java core provides the core of the Kinde SDK for the Java platform. This is necessary to install for connecting to Kinde.

Install from source

Link to this section

Clone the SDK repository.

Terminal window
git clone https://github.com/kinde-oss/kinde-java-sdk.git

Create a JAR file of your SDK project using the below command:

Terminal window
cd kinde-java-sdk
mvn clean install

Kinde’s SDK is available through Maven. To install it, add the following line to your pom.xml.

<dependency>
<groupId>com.kinde</groupId>
<artifactId>java-sdk</artifactId>
<version>2.0.0</version>
</dependency>

Add this dependency to your project’s build file:

Terminal window
repositories {
mavenCentral() // Needed if the ‘kinde’ jar has been published to maven central.
mavenLocal() // Needed if the ‘kinda’ jar has been published to the local maven repo.
}
dependencies {
implementation "com.kinde:java-sdk:2.0.0”
}

Connect to Kinde

Link to this section

Set up environment variables

Link to this section

The following environment variables are required for connecting to Kinde. This will enable the development of a M2M client service.

Terminal window
export KINDE_DOMAIN=https://<replace>.kinde.com # This is the domain you setup at kinde
export KINDE_CLIENT_ID=<replace> # the id for the client connecting to Kinde
export KINDE_CLIENT_SECRET=<replace> # the secret used to authenticate the client against Kinde

Provide a redirect URI, so a user’s login can be validated against Kinde.

Terminal window
export KINDE_REDIRECT_URI=http://localhost:8080/kinde-j2ee-app/login

The redirect URI/URL is used post successful login. It is the URL that the PKCE client CODE will be set to. A query parameter of ?code=‘value’ must be processed.

Set up .env files

Link to this section

The Kinde library supports .env files. The must be located in the directory from which the application is executed.

Terminal window
KINDE_DOMAIN=https://<replace>.kinde.com
KINDE_CLIENT_ID=<replace>
KINDE_CLIENT_SECRET=<replace>
KINDE_REDIRECT_URI=http://localhost:8080/kinde-j2ee-app/login

Core server example

Link to this section

To make a M2M server token request onto Kinde, set up the environment variables.

By shell export

Link to this section

Run these exports before running your service.

Terminal window
export KINDE_DOMAIN=https://<replace>.kinde.com # This is the domain you setup at kinde
export KINDE_CLIENT_ID=<replace> # the id for the client connecting to Kinde
export KINDE_CLIENT_SECRET=<replace> # the secret used to authenticate the client against Kinde

By .env file config

Link to this section

Place this .env file in the directory from which you run your service.

Terminal window
KINDE_DOMAIN=https://<replace>.kinde.com
KINDE_CLIENT_ID=<replace>
KINDE_CLIENT_SECRET=<replace>

Programmatic configuration

Link to this section

If you want to pass in configuration programmatically, use the KindeClientBuilder.

KindeClient kindeClient = KindeClientBuilder
.builder()
.domain("<replace>")
.clientId("<replace>")
.clientSecret("<replace>")
.build();

Retrieve a M2M token

Link to this section

The example below details how to implement a server-level token request. This is needed for M2M communication and authorization.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeClientSession kindeClientSession = kindeClient.clientSession();
KindeTokens tokens = kindeClientSession.retrieveTokens();

User Code Authorization Example (PKCE)

Link to this section

To authenticate a user on the client-side, configure as follows.

By shell export

Link to this section

Run these exports before running your service.

Terminal window
export KINDE_DOMAIN=https://<replace>.kinde.com # This is the domain you setup at kinde
export KINDE_CLIENT_ID=<replace> # the id for the client connecting to Kinde
export KINDE_CLIENT_SECRET=<replace> # the secret used to authenticate the client against Kinde
export KINDE_REDIRECT_URI=openid # the open id

By .env file config

Link to this section

Place this .env file in the directory from which you run your service.

Terminal window
KINDE_DOMAIN=https://<replace>.kinde.com
KINDE_CLIENT_ID=<replace>
KINDE_CLIENT_SECRET=<replace>
KINDE_REDIRECT_URI=<replace>
KINDE_SCOPES=openid

Programmatic configuration

Link to this section

If you want to pass in configuration programmatically, use the KindeClientBuilder.

KindeClient kindeClient = KindeClientBuilder
.builder()
.domain("<replace>")
.clientId("<replace>")
.clientSecret("<replace>")
.redirectUri("replace")
.addScope("openid")
.build();

Generate the redirect URL

Link to this section

Before the PKCE code can be processed, a user must be directed to Kinde to sign in. The client library can generate this URL as follows.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeClientSession kindeClientSession = kindeClient.clientSession();
AuthorizationUrl authorizationURL = kindeClientSession.authorizationUrl();

The AuthorizationUrl contains the url and CodeVerify information. If using a code grant the code verify needs to be stored for the redirect call. This can be done using the J2EE session. Here is an example

req.getSession().setAttribute("AuthorizationUrl",authorizationUrl);
resp.sendRedirect(authorizationUrl.getUrl().toString());

Request tokens upon redirect

Link to this section

If it is a code auth, then the AuthorizationUrl needs to be retrieved.

AuthorizationUrl authorizationUrl = (AuthorizationUrl)req.getSession().getAttribute("AuthorizationUrl");

The token request looks like the following.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();

Get user information

Link to this section

It is possible to retrieve user information using an AccessToken. In the example below, an access token is passed in a client session.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeClientSession kindeClientSession = kindeClient.getKindeClient().initClientSession(accessToken);
UserInfo userInfo = kindeClientSession.retrieveUserInfo();

Retrieve the user details for the code that has been authenticated.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeClientSession kindeClientSession = kindeClient.getKindeClient().initClientSession(code,authorizationUrl);
UserInfo userInfo = kindeClientSession.retrieveUserInfo();

The UserInfo object retrieved above contains the following member variables.

VariablesDescription
userInfoThe nimbus user object for more information
subjectThe subject of the user object
idThe id of the user on Kinde
givenNameThe given or first name of the user
familyNameThe family or surname of the user on Kinde
emailThe email address of the user on Kinde
pictureThe picture of the user on Kinde

API reference - for the Kinde core

Link to this section

The login process generates an authorization url. This can be used by the browser to initiate the login on Kinde, and once completed the user will be re-directed back.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeClientSession kindeClientSession = kindeClient.getKindeClient().clientSession();
AuthorizationUrl authorizationURL = kindeClientSession.login();

Send the redirect response using:

resp.sendRedirect(authorizationUrl.getUrl().toString());

register authenticate flow

Link to this section

The register process generates an authorization URL. This URL can be used to redirect the user to Kinde to register, and then redirect them back to complete the PKCE login.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeClientSession kindeClientSession = kindeClient.getKindeClient().clientSession();
AuthorizationUrl authorizationURL = kindeClientSession.register();

Send the redirect response using:

resp.sendRedirect(authorizationUrl.getUrl().toString());

The register process generates an authorization URL. This can be used by the browser to initiate the login.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeClientSession kindeClientSession = kindeClient.getKindeClient().clientSession();
AuthorizationUrl authorizationURL = kindeClientSession.logout();

Send the redirect response using:

resp.sendRedirect(authorizationUrl.getUrl().toString());

To complete authentication of a user and retrieve their tokens, do the following.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();

Retrieve a client session for the application and then retrieve the tokens for that client.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().clientSession().retrieveTokens();

createOrg authentication flow

Link to this section

The register process generates an authorization URL. This URL can be used to redirect the user to Kinde to register, and then redirect them back to complete the PKCE login.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeClientSession kindeClientSession = kindeClient.getKindeClient().clientSession();
AuthorizationUrl authorizationURL = kindeClientSession.createOrg("Org Value");

Send the redirect response using:

resp.sendRedirect(authorizationUrl.getUrl().toString());

Claims are available from the tokens.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
tokens.getAccessToken().getClaim("key");

The API on the token provides the getClaim method, which uses a key name to identify the claim in the token, and return the json object it refers to.

The permissions are available from the token.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
List<String> permissions = new ArrayList<String>();
permissions.addAll(tokens.getAccessToken().getPermissions());

getOrganization

Link to this section

The organization can be retrieved from the access token.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
List<String> organizations = new ArrayList<String>();
permissions.addAll(tokens.getAccessToken().getOrganizations());

getUserDetails

Link to this section

The user details are available either via the AccessToken or via the OAuth2 user info endpoint. Using the Token API:

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
tokens.getAccessToken()...
// retrieve user information
// username
// permissions
// claims
// feature flags

If this is not sufficient, the OAuth2 user info endpoint can be invoked. This can be done using an access token, or just after code auth. The following scopes ware required, openid, profile, email.

Using the code-created client:

KindeClientSession kindeClientSession = kindeClient.initClientSession(code, authorizationUrl);
UserInfo userInfo = kindeClientSession.retrieveUserInfo();
assertNotNull(userInfo);
assertNotNull(userInfo.getEmail());
assertNotNull(userInfo.getSubject());
assertNotNull(userInfo.getId());
assertNotNull(userInfo.getPicture());
assertNotNull(userInfo.getGivenName());
assertNotNull(userInfo.getFamilyName());

Using a token-created client:

KindeClientSession kindeClientSession = kindeClient2.initClientSession(accessToken);
UserInfo userInfo = kindeClientSession.retrieveUserInfo();
assertNotNull(userInfo);
assertNotNull(userInfo.getEmail());
assertNotNull(userInfo.getSubject());
assertNotNull(userInfo.getId());
assertNotNull(userInfo.getPicture());
assertNotNull(userInfo.getGivenName());
assertNotNull(userInfo.getFamilyName());

getUserOrganizations

Link to this section

The organization can be retrieved from the access token.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
List<String> organizations = new ArrayList<String>();
organizations.addAll(tokens.getAccessToken.getOrganizations());

The flags can be retrieved from the token. Once you have referenced the access token, the getFlag method can be called. This method returns a Map<String,Object>

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
tokens.getAccessToken().getFlags();

getBooleanFlag

Link to this section

This method returns a boolean value of the internal flag value.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
tokens.getAccessToken().getBooleanFlag(key);

This method returns a string value.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
tokens.getAccessToken().getStringFlag(key);

getIntegerFlag

Link to this section

The method returns the value for the key in type integer.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
tokens.getAccessToken().getIntegerFlag(key);

Kinde-J2EE API

Link to this section

This is the Kinde J2EE Library, and contains the core components needed to manage a client connection to the Kinde from a J2EE servlet container.

Project dependencies

Link to this section

In order to use this SDK include following POM dependency.

<dependency>
<groupId>com.kinde</groupId>
<artifactId>kinde-j2ee</artifactId>
<version>2.0.0</version>
</dependency>

In order to use the SDK with a Gradle build process please use the following dependency.

configuration('com.kinde:kinde-j2ee:2.0.0')

Project configuration

Link to this section

Configure the web.xml file to use these servlets.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>KindeLoginServlet</servlet-name>
<servlet-class>com.kinde.servlet.KindeLoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>KindeLogoutServlet</servlet-name>
<servlet-class>com.kinde.servlet.KindeLogoutServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>KindeRegisterServlet</servlet-name>
<servlet-class>com.kinde.servlet.KindeRegistrationServlet</servlet-class>
</servlet>
<filter>
<filter-name>KindeLoginFilter</filter-name>
<filter-class>com.kinde.filter.KindeLoginFilter</filter-class>
</filter>
<servlet-mapping>
<servlet-name>KindeLoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>KindeRegisterServlet</servlet-name>
<url-pattern>/register</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>KindeLogoutServlet</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<filter-mapping>
<filter-name>KindeLoginFilter</filter-name>
<url-pattern>/private/*</url-pattern> <!-- Apply to all URLs or specify specific patterns -->
</filter-mapping>
</web-app>

J2EE servlets and filters

Link to this section

The above project configuration sets up an example web.xml using the Kinde-J2EE servlets and filters. These are all you need to secure a J2EE project and can be used with Spring Boot or Quarkus:

  1. KindeLoginServlet: The servlet responsible for managing a login. It manages the re-direct to the Kinde Domain and and in the example above is setup to run from /login with the J2EE context.
  2. KindeRegisterServlet: This servlet is responsible for triggering the registration flow. It redirects to the configured Kinde domain and provides Kinde with the flags to indicate this is a user registration flow.
  3. KindeLogoutServlet: This servlet is responsible for triggering the logout flow, and for removing from the application any active session for the user.
  4. KindeLoginFilter: This is a J2EE filter and acts as a gateway to the private section of your site. It will deny users access to anything its scope covers, unless they have successfully authenticated. It also sets up roles or permissions for the logged in user.

Environment configuration

Link to this section

Configuration can either be performed by exports or through an .env file.

Terminal window
export KINDE_DOMAIN=https://<replace>.kinde.com # This is the domain you set up at kinde
export KINDE_CLIENT_ID=<replace> # the ID for the client connecting to Kinde
export KINDE_CLIENT_SECRET=<replace> # the secret used to authenticate the client against Kinde
export KINDE_REDIRECT_URI=http://localhost:8080/kinde-j2ee-app/login

The Kinde library supports .env files. The files must be located in the directory from which the application is executed.

Terminal window
KINDE_DOMAIN=https://<replace>.kinde.com
KINDE_CLIENT_ID=<replace>
KINDE_CLIENT_SECRET=<replace>
KINDE_REDIRECT_URI=http://localhost:8080/kinde-j2ee-app/login

Kinde Spring Boot starter

Link to this section

The Spring Boot starter manages all the dependencies required by a spring boot application connecting to Kinde.

Project Dependencies

Link to this section

To use configure Spring Boot to use Kinde for authentication, include the following dependency.

<dependency>
<groupId>com.kinde.spring</groupId>
<artifactId>kinde-springboot-starter</artifactId>
<version>2.0.0</version>
</dependency>

To use the SDK with a Gradle build process, use the following dependency.

configuration('com.kinde.spring:kinde-springboot-starter:2.0.0')

This library can be configured in different ways, via environment variables, via .env file and via the Spring Boot application.yaml file.

Environment configuration

Link to this section
Terminal window
export KINDE_DOMAIN=https://<replace>.kinde.com # This is the domain you setup at kinde
export KINDE_CLIENT_ID=<replace> # the id for the client connecting to Kinde
export KINDE_CLIENT_SECRET=<replace> # the secret used to authenticate the client against Kinde
export KINDE_REDIRECT_URI=http://localhost:< replace with port of application server >/kinde-j2ee-app/login
export KINDE_GRANT_TYPE=CODE
export KINDE_SCOPES=profile,email,openid
Terminal window
KINDE_DOMAIN=https://<replace>.kinde.com # This is the domain you setup at kinde
KINDE_CLIENT_ID=<replace> # the id for the client connecting to Kinde
KINDE_CLIENT_SECRET=<replace> # the secret used to authenticate the client against Kinde
KINDE_REDIRECT_URI=http://localhost:< replace with port of application server >/kinde-j2ee-app/login
KINDE_GRANT_TYPE=CODE
KINDE_SCOPES=profile,email,openid

application.yaml

Link to this section
kinde:
oauth2:
domain: https://< replace >.kinde.com
client-id: < replace >
client-secret: < replace >
scopes: openid,email,profile

Kinde Management API

Link to this section

You can access Kinde’s API endpoints through the Kinde Management API. This lets developers work programmatically, rather than through the main Kinde interface.

The Kinde Management Library contains the components needed to access the Kinde Management API. It includes an OpenAPI-generated stub and a KindeAdminSession tool that instantiates the ApiClient using OIDC details.

Project Dependencies

Link to this section

To use this SDK, include the following dependency in your pom.xml:

<dependency>
<groupId>com.kinde</groupId>
<artifactId>kinde-management</artifactId>
<version>2.0.0</version>
</dependency>

For Gradle, add the following dependency to your build file:

implementation('com.kinde:kinde-management:2.0.0')

Building the SDK from Source

Link to this section
  1. Clone the repository to your machine:

    Terminal window
    git clone https://github.com/kinde-oss/kinde-java-sdk
  2. Go into the project:

    Terminal window
    cd kinde-java-sdk
  3. Install the dependencies:

    Terminal window
    mvn clean install

Maven automatically downloads the dependency from your local repository and makes it available in your project.

Set up environment variables

Link to this section

The following basic environment variables are required at a mimimum for connecting to the Kinde Management API.

Terminal window
export KINDE_DOMAIN=https://<replace>.kinde.com # This is the domain you setup at kinde
export KINDE_CLIENT_ID=<replace> # the id for the client connecting to Kinde
export KINDE_CLIENT_SECRET=<replace> # the secret used to authenticate the client against Kinde
export KINDE_SCOPES=openid # the scope as we are using an OpenID connection
export KINDE_AUDIENCE=https://<replace>.kinde.com/api # the audience we need access to

Set up .env files

Link to this section

The Kinde library supports .env files. The must be located in the directory from which the application is executed.

Terminal window
KINDE_DOMAIN=https://burntjam.kinde.com
KINDE_CLIENT_ID=<replace>
KINDE_CLIENT_SECRET=<replace>
KINDE_SCOPES=openid
KINDE_AUDIENCE=https://<replace>.kinde.com/api

Programmatic configuration

Link to this section

If you want to pass in configuration programmatically, the KindeClientBuilder supports the following approach.

KindeClient kindeClient = KindeClientBuilder
.builder()
.domain("<replace>")
.clientId("<replace>")
.clientSecret("<replace>")
.addScope("<replace>")
.addAudience("https://<replace>.kinde.com/api")
.build();
Get an ApiClient
Link to this section

This example gets an ApiClient instance and then creates an ApplicationApi instance using the ApiClient.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeAdminSession kindeAdminSession = KindeAdminSessionBuilder.builder().client(kindeClient).build();
ApiClient apiClient = kindeAdminSession.initClient();
ApplicationsApi applicationsApi = new ApplicationsApi(apiClient);

Register your first user by signing up yourself. You’ll see your newly registered user on the Users page in Kinde.

User Permissions

Link to this section

The user permissions are available in two ways. One is from the ID token as a claim, the other is via the Kinde Management API.

Permissions in token

Link to this section
KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeTokens tokens = kindeClient.getKindeClient().initClientSession(code,authorizationUrl).retrieveTokens();
List<String> permissions = new ArrayList<String>();
permissions.addAll(tokens.getAccessToken().getPermissions());

Permissions via the Management API

Link to this section

The permissions are up to you to define. The code below provides an example on how to retrieve the permissions from the portal using the Kinde Management API.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeAdminSession kindeAdminSession = KindeAdminSessionBuilder.builder().client(kindeClient).build();
ApiClient apiClient = kindeAdminSession.initClient();
OrganizationApi organizationApi = new OrganizationApi(apiClient);
// org code is the org that the user is associated with
// user id is the user
// expanded
organizationApi.getOrganizationUserPermissions(orgCode, userId, expand)

Create an organization

Link to this section

Use the OrganizationApi to create a new organization.

KindeClient kindeClient = KindeClientBuilder
.builder()
.build();
KindeAdminSession kindeAdminSession = KindeAdminSessionBuilder.builder().client(kindeClient).build();
ApiClient apiClient = kindeAdminSession.initClient();
OrganizationApi organizationApi = new OrganizationApi(apiClient);
// org code is the org that the user is associated with
// user id is the user
// expanded
organizationApi.createOrganization(new CreateOrganizationRequest().name("test"));

If you need help connecting to Kinde, please contact us at support@kinde.com.