Apereo CAS Core Utilities - A comprehensive utility library providing functional programming constructs, encryption utilities, configuration helpers, and core infrastructure components for the Central Authentication Service framework
—
Random string and numeric generators for creating secure tokens, identifiers, session IDs, and cryptographic material with multiple output formats and configurable algorithms.
Core interface for random string generation with configurable length and algorithms.
public interface RandomStringGenerator {
// Default configuration
int DEFAULT_LENGTH = 36;
// Configuration methods
long getDefaultLength();
String getAlgorithm();
// String generation methods
String getNewString(int size);
String getNewString();
// Binary generation method
byte[] getNewStringAsBytes(int size);
}Basic string generation:
@Service
public class TokenService {
private final RandomStringGenerator generator;
public TokenService(RandomStringGenerator generator) {
this.generator = generator;
}
public String generateSessionToken() {
// Use default length (36 characters)
return generator.getNewString();
}
public String generateApiKey() {
// Custom length for API keys
return generator.getNewString(64);
}
public String generateShortCode() {
// Short codes for verification
return generator.getNewString(8);
}
public byte[] generateBinaryToken() {
// Generate as bytes for binary protocols
return generator.getNewStringAsBytes(32);
}
}Abstract base implementation providing common functionality for string generators.
public abstract class AbstractRandomStringGenerator implements RandomStringGenerator {
// Protected fields
protected final SecureRandom randomizer;
protected final String algorithm;
protected final long defaultLength;
// Constructor
protected AbstractRandomStringGenerator(long defaultLength);
protected AbstractRandomStringGenerator(long defaultLength, String algorithm);
// Interface implementation
@Override
public long getDefaultLength();
@Override
public String getAlgorithm();
@Override
public String getNewString();
@Override
public byte[] getNewStringAsBytes(int size);
// Abstract methods for subclasses
protected abstract String convertBytesToString(byte[] bytes);
}Default implementation using alphanumeric characters with secure random generation.
public class DefaultRandomStringGenerator extends AbstractRandomStringGenerator {
// Default character set (alphanumeric)
public static final String DEFAULT_CHARSET =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
// Constructors
public DefaultRandomStringGenerator();
public DefaultRandomStringGenerator(long defaultLength);
public DefaultRandomStringGenerator(long defaultLength, String charset);
// String generation implementation
@Override
public String getNewString(int size);
// Byte conversion implementation
@Override
protected String convertBytesToString(byte[] bytes);
}Default generator configuration:
@Configuration
public class GeneratorConfiguration {
@Bean
@Primary
public RandomStringGenerator defaultStringGenerator() {
return new DefaultRandomStringGenerator();
}
@Bean("shortCodeGenerator")
public RandomStringGenerator shortCodeGenerator() {
// Custom length for short codes
return new DefaultRandomStringGenerator(8);
}
@Bean("customCharsetGenerator")
public RandomStringGenerator customCharsetGenerator() {
// Custom character set (uppercase only)
String charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new DefaultRandomStringGenerator(12, charset);
}
}Usage in services:
@Service
public class UserRegistrationService {
private final RandomStringGenerator defaultGenerator;
private final RandomStringGenerator shortCodeGenerator;
public UserRegistrationService(
@Qualifier("defaultStringGenerator") RandomStringGenerator defaultGenerator,
@Qualifier("shortCodeGenerator") RandomStringGenerator shortCodeGenerator) {
this.defaultGenerator = defaultGenerator;
this.shortCodeGenerator = shortCodeGenerator;
}
public User createUser(String email, String password) {
User user = new User();
user.setEmail(email);
user.setPasswordHash(hashPassword(password));
// Generate unique user ID
user.setUserId(defaultGenerator.getNewString(32));
// Generate verification code
user.setVerificationCode(shortCodeGenerator.getNewString());
return userRepository.save(user);
}
}Generator producing Base64-encoded random strings for URL-safe tokens and identifiers.
public class Base64RandomStringGenerator extends AbstractRandomStringGenerator {
// Constructors
public Base64RandomStringGenerator();
public Base64RandomStringGenerator(long defaultLength);
// String generation with Base64 encoding
@Override
public String getNewString(int size);
// Byte conversion to Base64
@Override
protected String convertBytesToString(byte[] bytes);
}Generator producing hexadecimal random strings for cryptographic applications and debugging.
public class HexRandomStringGenerator extends AbstractRandomStringGenerator {
// Constructors
public HexRandomStringGenerator();
public HexRandomStringGenerator(long defaultLength);
// String generation with hex encoding
@Override
public String getNewString(int size);
// Byte conversion to hexadecimal
@Override
protected String convertBytesToString(byte[] bytes);
}Specialized generators for different use cases:
@Component
public class CryptographicTokenService {
private final Base64RandomStringGenerator base64Generator;
private final HexRandomStringGenerator hexGenerator;
public CryptographicTokenService() {
this.base64Generator = new Base64RandomStringGenerator(32);
this.hexGenerator = new HexRandomStringGenerator(16);
}
public String generateJwtSecret() {
// Base64 for JWT secrets (URL-safe)
return base64Generator.getNewString(64);
}
public String generateCsrfToken() {
// Base64 for CSRF tokens
return base64Generator.getNewString(32);
}
public String generateSalt() {
// Hex for password salts
return hexGenerator.getNewString(32);
}
public String generateKeyId() {
// Hex for key identifiers
return hexGenerator.getNewString(8);
}
public String generateNonce() {
// Base64 for cryptographic nonces
return base64Generator.getNewString(16);
}
}Interface for generating numeric identifiers and sequences.
public interface NumericGenerator {
// Numeric generation methods
long getNextLong();
int getNextInt();
// Configuration
long getMinValue();
long getMaxValue();
}Specialized interface for long numeric generation with extended range support.
public interface LongNumericGenerator extends NumericGenerator {
// Extended long generation
long getNextLongValue();
long getNextLongValue(long min, long max);
// Range configuration
void setRange(long min, long max);
}Default implementation for long numeric generation with configurable ranges.
public class DefaultLongNumericGenerator implements LongNumericGenerator {
// Default range constants
public static final long DEFAULT_MIN_VALUE = 1L;
public static final long DEFAULT_MAX_VALUE = Long.MAX_VALUE;
// Constructors
public DefaultLongNumericGenerator();
public DefaultLongNumericGenerator(long minValue, long maxValue);
// NumericGenerator implementation
@Override
public long getNextLong();
@Override
public int getNextInt();
@Override
public long getMinValue();
@Override
public long getMaxValue();
// LongNumericGenerator implementation
@Override
public long getNextLongValue();
@Override
public long getNextLongValue(long min, long max);
@Override
public void setRange(long min, long max);
}General-purpose random number generator for various numeric types.
public class DefaultRandomNumberGenerator implements NumericGenerator {
// Constructors
public DefaultRandomNumberGenerator();
public DefaultRandomNumberGenerator(SecureRandom random);
// NumericGenerator implementation
@Override
public long getNextLong();
@Override
public int getNextInt();
@Override
public long getMinValue();
@Override
public long getMaxValue();
// Additional random methods
public double getNextDouble();
public float getNextFloat();
public boolean getNextBoolean();
public byte[] getNextBytes(int count);
}Numeric ID generation:
@Service
public class IdentifierService {
private final LongNumericGenerator longGenerator;
private final NumericGenerator randomGenerator;
public IdentifierService() {
// Sequential IDs in a specific range
this.longGenerator = new DefaultLongNumericGenerator(100000L, 999999L);
// Random numbers
this.randomGenerator = new DefaultRandomNumberGenerator();
}
public Long generateUserId() {
// Generate user IDs in range
return longGenerator.getNextLongValue();
}
public String generateOrderNumber() {
// Combine timestamp with random number
long timestamp = System.currentTimeMillis();
int random = randomGenerator.getNextInt();
return String.format("ORD-%d-%06d", timestamp, Math.abs(random % 1000000));
}
public Long generateSessionId() {
// Random session ID
return randomGenerator.getNextLong();
}
}@Service
@Slf4j
public class TokenGenerationService {
private final RandomStringGenerator alphanumericGenerator;
private final RandomStringGenerator base64Generator;
private final RandomStringGenerator hexGenerator;
private final LongNumericGenerator sequentialGenerator;
private final NumericGenerator randomNumericGenerator;
public TokenGenerationService() {
// Initialize different generators
this.alphanumericGenerator = new DefaultRandomStringGenerator(32);
this.base64Generator = new Base64RandomStringGenerator(24);
this.hexGenerator = new HexRandomStringGenerator(16);
this.sequentialGenerator = new DefaultLongNumericGenerator(1000000L, 9999999L);
this.randomNumericGenerator = new DefaultRandomNumberGenerator();
}
public AuthenticationToken generateAuthToken(String userId) {
AuthenticationToken token = new AuthenticationToken();
// Primary token (Base64 for URL safety)
token.setAccessToken(base64Generator.getNewString(32));
// Refresh token (longer alphanumeric)
token.setRefreshToken(alphanumericGenerator.getNewString(64));
// Token ID (sequential for tracking)
token.setTokenId(sequentialGenerator.getNextLongValue());
// CSRF token (hex for web forms)
token.setCsrfToken(hexGenerator.getNewString(32));
// Expiration (current time + random offset)
long baseExpiry = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1);
long randomOffset = randomNumericGenerator.getNextInt() % TimeUnit.MINUTES.toMillis(5);
token.setExpiresAt(baseExpiry + randomOffset);
log.info("Generated authentication token {} for user {}", token.getTokenId(), userId);
return token;
}
public SessionData generateSession(String username) {
SessionData session = new SessionData();
// Session ID (Base64 encoded)
session.setSessionId(base64Generator.getNewString(48));
// CSRF protection token
session.setCsrfToken(hexGenerator.getNewString(24));
// Random session timeout (base + jitter)
int baseTimeout = 1800; // 30 minutes
int jitter = randomNumericGenerator.getNextInt() % 300; // ±5 minutes
session.setTimeoutSeconds(baseTimeout + jitter);
log.info("Generated session {} for user {}", session.getSessionId(), username);
return session;
}
public VerificationCode generateVerificationCode(VerificationCodeType type) {
VerificationCode code = new VerificationCode();
switch (type) {
case EMAIL_VERIFICATION:
// 6-digit numeric code
code.setCode(String.format("%06d",
Math.abs(randomNumericGenerator.getNextInt() % 1000000)));
code.setExpiryMinutes(15);
break;
case SMS_VERIFICATION:
// 4-digit numeric code
code.setCode(String.format("%04d",
Math.abs(randomNumericGenerator.getNextInt() % 10000)));
code.setExpiryMinutes(5);
break;
case PASSWORD_RESET:
// Long alphanumeric token
code.setCode(alphanumericGenerator.getNewString(48));
code.setExpiryMinutes(60);
break;
case API_KEY:
// Base64 API key with prefix
String apiKey = base64Generator.getNewString(32);
code.setCode("cas_" + apiKey.replace("+", "-").replace("/", "_"));
code.setExpiryMinutes(0); // No expiry for API keys
break;
}
return code;
}
public String generateTraceId() {
// Hex trace ID for distributed tracing
return hexGenerator.getNewString(16);
}
public String generateCorrelationId() {
// UUID-like correlation ID
String hex32 = hexGenerator.getNewString(32);
return String.format("%s-%s-%s-%s-%s",
hex32.substring(0, 8),
hex32.substring(8, 12),
hex32.substring(12, 16),
hex32.substring(16, 20),
hex32.substring(20, 32));
}
}
enum VerificationCodeType {
EMAIL_VERIFICATION,
SMS_VERIFICATION,
PASSWORD_RESET,
API_KEY
}Configuration for production use:
@Configuration
@EnableConfigurationProperties(GeneratorProperties.class)
public class ProductionGeneratorConfiguration {
@Bean
@ConditionalOnMissingBean
public RandomStringGenerator secureStringGenerator(GeneratorProperties properties) {
return new DefaultRandomStringGenerator(
properties.getDefaultStringLength(),
properties.getCharacterSet()
);
}
@Bean
@ConditionalOnMissingBean
public LongNumericGenerator sequentialIdGenerator(GeneratorProperties properties) {
return new DefaultLongNumericGenerator(
properties.getSequentialMinValue(),
properties.getSequentialMaxValue()
);
}
@ConfigurationProperties(prefix = "cas.generator")
@Data
public static class GeneratorProperties {
private int defaultStringLength = 32;
private String characterSet = DefaultRandomStringGenerator.DEFAULT_CHARSET;
private long sequentialMinValue = 1000000L;
private long sequentialMaxValue = Long.MAX_VALUE;
}
}This generator library provides secure, configurable, and efficient random generation capabilities for all types of identifiers and tokens needed in CAS authentication systems.
Install with Tessl CLI
npx tessl i tessl/maven-org-apereo-cas--cas-server-core-util-api