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.
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
.
The Kinde Java core provides the core of the Kinde SDK for the Java platform. This is necessary to install for connecting to Kinde.
Clone the SDK repository.
git clone https://github.com/kinde-oss/kinde-java-sdk.git
Create a JAR file of your SDK project using the below command:
Kinde’s SDK is available through Maven . To install it, add the following line to your pom.xml
.
< groupId > com . kinde </ groupId >
< artifactId > java - sdk </ artifactId >
Add this dependency to your project’s build file:
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.
implementation " com.kinde:java-sdk:2.0.0”
The following environment variables are required for connecting to Kinde. This will enable the development of a M2M client service.
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.
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.
The Kinde library supports .env files. The must be located in the directory from which the application is executed.
KINDE_DOMAIN = https://<replace>.kinde.com
KINDE_CLIENT_ID = <replace>
KINDE_CLIENT_SECRET = <replace>
KINDE_REDIRECT_URI = http://localhost:8080/kinde-j2ee-app/login
To make a M2M server token request onto Kinde, set up the environment variables.
Run these exports before running your service.
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
Place this .env file in the directory from which you run your service.
KINDE_DOMAIN = https://<replace>.kinde.com
KINDE_CLIENT_ID = <replace>
KINDE_CLIENT_SECRET = <replace>
If you want to pass in configuration programmatically, use the KindeClientBuilder
.
KindeClient kindeClient = KindeClientBuilder
. clientSecret ( " <replace> " )
The example below details how to implement a server-level token request. This is needed for M2M communication and authorization.
KindeClient kindeClient = KindeClientBuilder
KindeClientSession kindeClientSession = kindeClient . clientSession ();
KindeTokens tokens = kindeClientSession . retrieveTokens ();
To authenticate a user on the client-side, configure as follows.
Run these exports before running your service.
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
Place this .env file in the directory from which you run your service.
KINDE_DOMAIN = https://<replace>.kinde.com
KINDE_CLIENT_ID = <replace>
KINDE_CLIENT_SECRET = <replace>
KINDE_REDIRECT_URI = <replace>
If you want to pass in configuration programmatically, use the KindeClientBuilder
.
KindeClient kindeClient = KindeClientBuilder
. clientSecret ( " <replace> " )
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
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 ());
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
KindeTokens tokens = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl ) . retrieveTokens ();
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
KindeClientSession kindeClientSession = kindeClient . getKindeClient () . initClientSession ( accessToken );
UserInfo userInfo = kindeClientSession . retrieveUserInfo ();
Retrieve the user details for the code that has been authenticated.
KindeClient kindeClient = KindeClientBuilder
KindeClientSession kindeClientSession = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl );
UserInfo userInfo = kindeClientSession . retrieveUserInfo ();
The UserInfo object retrieved above contains the following member variables.
Variables Description userInfo The nimbus user object for more information subject The subject of the user object id The id of the user on Kinde givenName The given or first name of the user familyName The family or surname of the user on Kinde email The email address of the user on Kinde picture The picture of the user on Kinde
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
KindeClientSession kindeClientSession = kindeClient . getKindeClient () . clientSession ();
AuthorizationUrl authorizationURL = kindeClientSession . login ();
Send the redirect response using:
resp . sendRedirect ( authorizationUrl . getUrl () . toString ());
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
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
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
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
KindeTokens tokens = kindeClient . getKindeClient () . clientSession () . retrieveTokens ();
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
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
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
KindeTokens tokens = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl ) . retrieveTokens ();
List < String > permissions = new ArrayList < String >();
permissions . addAll ( tokens . getAccessToken () . getPermissions ());
The organization can be retrieved from the access token.
KindeClient kindeClient = KindeClientBuilder
KindeTokens tokens = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl ) . retrieveTokens ();
List < String > organizations = new ArrayList < String >();
permissions . addAll ( tokens . getAccessToken () . getOrganizations ());
The user details are available either via the AccessToken or via the OAuth2 user info endpoint. Using the Token API:
KindeClient kindeClient = KindeClientBuilder
KindeTokens tokens = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl ) . retrieveTokens ();
tokens . getAccessToken () ...
// retrieve user information
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 . 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 . getEmail ());
assertNotNull ( userInfo . getSubject ());
assertNotNull ( userInfo . getId ());
assertNotNull ( userInfo . getPicture ());
assertNotNull ( userInfo . getGivenName ());
assertNotNull ( userInfo . getFamilyName ());
The organization can be retrieved from the access token.
KindeClient kindeClient = KindeClientBuilder
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
KindeTokens tokens = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl ) . retrieveTokens ();
tokens . getAccessToken () . getFlags ();
This method returns a boolean value of the internal flag value.
KindeClient kindeClient = KindeClientBuilder
KindeTokens tokens = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl ) . retrieveTokens ();
tokens . getAccessToken () . getBooleanFlag ( key );
This method returns a string value.
KindeClient kindeClient = KindeClientBuilder
KindeTokens tokens = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl ) . retrieveTokens ();
tokens . getAccessToken () . getStringFlag ( key );
The method returns the value for the key in type integer.
KindeClient kindeClient = KindeClientBuilder
KindeTokens tokens = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl ) . retrieveTokens ();
tokens . getAccessToken () . getIntegerFlag ( key );
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.
In order to use this SDK include following POM dependency.
< groupId > com.kinde </ groupId >
< artifactId > kinde-j2ee </ artifactId >
In order to use the SDK with a Gradle build process please use the following dependency.
configuration ( ' com.kinde:kinde-j2ee:2.0.0 ' )
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 "
< servlet-name > KindeLoginServlet </ servlet-name >
< servlet-class > com.kinde.servlet.KindeLoginServlet </ servlet-class >
< servlet-name > KindeLogoutServlet </ servlet-name >
< servlet-class > com.kinde.servlet.KindeLogoutServlet </ servlet-class >
< servlet-name > KindeRegisterServlet </ servlet-name >
< servlet-class > com.kinde.servlet.KindeRegistrationServlet </ servlet-class >
< filter-name > KindeLoginFilter </ filter-name >
< filter-class > com.kinde.filter.KindeLoginFilter </ filter-class >
< servlet-name > KindeLoginServlet </ servlet-name >
< url-pattern > /login </ url-pattern >
< servlet-name > KindeRegisterServlet </ servlet-name >
< url-pattern > /register </ url-pattern >
< servlet-name > KindeLogoutServlet </ servlet-name >
< url-pattern > /logout </ url-pattern >
< filter-name > KindeLoginFilter </ filter-name >
< url-pattern > /private/* </ url-pattern > <!-- Apply to all URLs or specify specific patterns -->
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:
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.
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.
KindeLogoutServlet: This servlet is responsible for triggering the logout flow, and for removing from the application any active session for the user.
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.
Configuration can either be performed by exports or through an .env file.
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.
KINDE_DOMAIN = https://<replace>.kinde.com
KINDE_CLIENT_ID = <replace>
KINDE_CLIENT_SECRET = <replace>
KINDE_REDIRECT_URI = http://localhost:8080/kinde-j2ee-app/login
The Spring Boot starter manages all the dependencies required by a spring boot application connecting to Kinde.
To use configure Spring Boot to use Kinde for authentication, include the following dependency.
< groupId > com.kinde.spring </ groupId >
< artifactId > kinde-springboot-starter </ artifactId >
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.
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
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_SCOPES = profile,email,openid
domain : https://< replace >.kinde.com
client-secret : < replace >
scopes : openid,email,profile
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.
To use this SDK, include the following dependency in your pom.xml
:
< groupId > com.kinde </ groupId >
< artifactId > kinde-management </ artifactId >
For Gradle, add the following dependency to your build file:
implementation ( ' com.kinde:kinde-management:2.0.0 ' )
Clone the repository to your machine:
git clone https://github.com/kinde-oss/kinde-java-sdk
Go into the project:
Install the dependencies:
Maven automatically downloads the dependency from your local repository and makes it available in your project.
The following basic environment variables are required at a mimimum for connecting to the Kinde Management API.
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
The Kinde library supports .env files. The must be located in the directory from which the application is executed.
KINDE_DOMAIN = https://burntjam.kinde.com
KINDE_CLIENT_ID = <replace>
KINDE_CLIENT_SECRET = <replace>
KINDE_AUDIENCE = https://<replace>.kinde.com/api
If you want to pass in configuration programmatically, the KindeClientBuilder
supports the following approach.
KindeClient kindeClient = KindeClientBuilder
. clientSecret ( " <replace> " )
. addAudience ( " https://<replace>.kinde.com/api " )
This example gets an ApiClient
instance and then creates an ApplicationApi
instance using the ApiClient
.
KindeClient kindeClient = KindeClientBuilder
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.
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.
KindeClient kindeClient = KindeClientBuilder
KindeTokens tokens = kindeClient . getKindeClient () . initClientSession ( code , authorizationUrl ) . retrieveTokens ();
List < String > permissions = new ArrayList < String >();
permissions . addAll ( tokens . getAccessToken () . getPermissions ());
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
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
organizationApi . getOrganizationUserPermissions ( orgCode , userId , expand )
Use the OrganizationApi
to create a new organization.
KindeClient kindeClient = KindeClientBuilder
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
organizationApi . createOrganization ( new CreateOrganizationRequest () . name ( " test " ));
If you need help connecting to Kinde, please contact us at support@kinde.com .