Token endpoint in Java

This article presents a simple token endpoint example for creating JSON Web Tokens (JWT) implemented in Java. The tokens are used by CKEditor Cloud Services to authenticate users.

# Dependencies

Both examples use jjwt library for creating tokens.

For installation instructions check the official guide.

# Examples

When creating a token endpoint to integrate with Collaboration, the token payload should contain the environment ID and user data.

# Real-time collaboration features

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.security.Key;

public class Main {

    private static String createCSToken(String accessKey, String environmentId) throws UnsupportedEncodingException {
        Key key = Keys.hmacShaKeyFor(accessKey.getBytes("ASCII"));

        Map<String, Object> payload = new HashMap<>() {{
            put("aud", environmentId);
            put("iat", System.currentTimeMillis() / 1000);
            put("sub", "user-123");
            put("user", new HashMap<>() {{
                put("email", "joe.doe@example.com");
                put("name", "Joe Doe");
            }});
            put("auth", new HashMap<>() {{
                put("collaboration", new HashMap<>() {{
                    put("*", new HashMap<>() {{
                        put("role", "writer");
                    }});
                }});
            }});
        }};

        return Jwts.builder().addClaims(payload).signWith(key).compact();
    }

    public static void main(String[] args) {
        String accessKey = "w1lnWEN63FPKxBNmxHN7WpfW2IoYVYca5moqIUKfWesL1Ykwv34iR5xwfWLy";
        String environmentId = "LJRQ1bju55p6a47RwadH";

        try {
            var tokenString = createCSToken(accessKey, environmentId);

            // Here we are printing the token to the console. In a real usage scenario
            // it should be returned in an HTTP response of the token endpoint.
            System.out.println(tokenString);
        } catch (Exception exception) {
            System.out.println(exception);
        }
    }
}

accessKey and environmentId should be replaced with the keys provided by the CKEditor Ecosystem customer dashboard for SaaS or by the Management Panel for the On-Premises application. User data can be taken from the session or the database.

You should then pass the token to the client in an HTTP response of the token endpoint. Do not forget to authenticate the user in your application before you send the token. If the user is unauthenticated, the token endpoint should return an error or redirect to the login page. You should also make sure the token is sent via an encrypted channel.

# Easy Image, Export to PDF and Import and Export to Word

The token endpoint for Easy Image and the Export to Word/PDF features does not require adding user data. You can therefore skip the user and auth properties in the token payload.

# Export to PDF and Import and Export to Word On-Premises

Tokens for PDF Converter and DOCX Converter On-Premises do not require any additional claims, so you can create the token with an empty payload.

In this implementation, accessKey has been replaced by SECRET_KEY - a variable set during the Import and Export to Word/Export to PDF On-Premises instance installation.

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.security.Key;

public class Main {
    private static String createCSToken(String secretKey) throws UnsupportedEncodingException {
        Key key = Keys.hmacShaKeyFor(secretKey.getBytes("ASCII"));

        return Jwts.builder().setIssuedAt(new Date()).signWith(key).compact();
    }

    public static void main(String[] args) {
        String secretKey = "w1lnWEN63FPKxBNmxHN7WpfW2IoYVYca5moqIUKfWesL1Ykwv34iR5xwfWLy";

        try {
            var tokenString = createCSToken(secretKey);

            // Here we are printing the token to the console. In a real usage scenario
            // it should be returned in an HTTP response of the token endpoint.
            System.out.println(tokenString);
        } catch (Exception exception) {
            System.out.println(exception);
        }
    }
}

# Example response

The result should be in a plain text format.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJMSlJRMWJqdTU1cDZhNDdSd2FkSCIsImlhdCI6MTY0OTIyOTQyMiwic3ViIjoidXNlci0xMjMiLCJ1c2VyIjp7ImVtYWlsIjoiam9lLmRvZUBleGFtcGxlLmNvbSIsIm5hbWUiOiJKb2UgRG9lIn0sImF1dGgiOnsiY29sbGFib3JhdGlvbiI6eyIqIjp7InJvbGUiOiJ3cml0ZXIifX19fQ._V-HXKKHU1E-saZxk4JTvgXdh1I7793nCEK91ubSZHY

# Debugging

For debugging purposes jwt.io can be used.