or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdconfiguration.mdindex.mdjson-serialization.mdticket-caching.mduser-details.mdweb-integration.md

ticket-caching.mddocs/

0

# Ticket Caching

1

2

Stateless ticket caching implementations for performance optimization in clustered and stateless authentication scenarios. These components provide caching strategies to avoid repeated CAS server validation calls for the same service tickets.

3

4

## Capabilities

5

6

### Stateless Ticket Cache Interface

7

8

Core interface defining ticket caching operations for stateless CAS authentication scenarios.

9

10

```java { .api }

11

/**

12

* Interface for caching CAS authentication tokens to avoid repeated server validation.

13

* Used in stateless authentication scenarios where tickets need to be validated multiple times.

14

*/

15

public interface StatelessTicketCache {

16

17

/**

18

* Gets a cached authentication token by service ticket ID.

19

* @param serviceTicket the CAS service ticket to look up

20

* @return cached CasAuthenticationToken or null if not found or expired

21

*/

22

CasAuthenticationToken getByTicketId(String serviceTicket);

23

24

/**

25

* Stores an authentication token in the cache.

26

* @param token the CasAuthenticationToken to cache

27

* @throws IllegalArgumentException if token is null or invalid

28

*/

29

void putTicketInCache(CasAuthenticationToken token);

30

31

/**

32

* Removes an authentication token from the cache.

33

* @param token the CasAuthenticationToken to remove

34

*/

35

void removeTicketFromCache(CasAuthenticationToken token);

36

37

/**

38

* Removes an authentication token from the cache by service ticket ID.

39

* @param serviceTicket the service ticket ID to remove

40

*/

41

void removeTicketFromCache(String serviceTicket);

42

}

43

```

44

45

### Null Stateless Ticket Cache

46

47

No-operation implementation that disables ticket caching entirely.

48

49

```java { .api }

50

/**

51

* No-operation implementation of StatelessTicketCache that performs no caching.

52

* All operations are no-ops, effectively disabling ticket caching.

53

* Used when caching is not desired or in development environments.

54

*/

55

public final class NullStatelessTicketCache implements StatelessTicketCache {

56

57

/**

58

* Always returns null, indicating no cached ticket found.

59

* @param serviceTicket the service ticket (ignored)

60

* @return null always

61

*/

62

public CasAuthenticationToken getByTicketId(String serviceTicket);

63

64

/**

65

* No-operation method that does not store the token.

66

* @param token the token to cache (ignored)

67

*/

68

public void putTicketInCache(CasAuthenticationToken token);

69

70

/**

71

* No-operation method that does not remove anything.

72

* @param token the token to remove (ignored)

73

*/

74

public void removeTicketFromCache(CasAuthenticationToken token);

75

76

/**

77

* No-operation method that does not remove anything.

78

* @param serviceTicket the service ticket to remove (ignored)

79

*/

80

public void removeTicketFromCache(String serviceTicket);

81

}

82

```

83

84

**Usage Example:**

85

86

```java

87

@Bean

88

public StatelessTicketCache nullTicketCache() {

89

return new NullStatelessTicketCache();

90

}

91

```

92

93

### Spring Cache-Based Ticket Cache

94

95

Production-ready implementation using Spring's cache abstraction for distributed caching support.

96

97

```java { .api }

98

/**

99

* StatelessTicketCache implementation backed by Spring's Cache abstraction.

100

* Supports various cache providers (Redis, Hazelcast, Ehcache, etc.) through Spring Cache.

101

*/

102

public class SpringCacheBasedTicketCache implements StatelessTicketCache {

103

104

/**

105

* Creates cache implementation with specified Spring Cache instance.

106

* @param cache Spring Cache instance to use for storage

107

* @throws IllegalArgumentException if cache is null

108

*/

109

public SpringCacheBasedTicketCache(Cache cache);

110

111

/**

112

* Retrieves cached authentication token by service ticket ID.

113

* @param serviceTicket the service ticket to look up

114

* @return cached CasAuthenticationToken or null if not found

115

*/

116

public CasAuthenticationToken getByTicketId(String serviceTicket);

117

118

/**

119

* Stores authentication token in the cache using the service ticket as key.

120

* @param token the CasAuthenticationToken to cache (must not be null)

121

* @throws IllegalArgumentException if token or its credentials are null

122

*/

123

public void putTicketInCache(CasAuthenticationToken token);

124

125

/**

126

* Removes authentication token from cache.

127

* @param token the token to remove (uses token's credentials as key)

128

*/

129

public void removeTicketFromCache(CasAuthenticationToken token);

130

131

/**

132

* Removes authentication token from cache by service ticket ID.

133

* @param serviceTicket the service ticket ID to remove from cache

134

*/

135

public void removeTicketFromCache(String serviceTicket);

136

}

137

```

138

139

**Usage Example:**

140

141

```java

142

@Configuration

143

@EnableCaching

144

public class TicketCacheConfig {

145

146

@Bean

147

public CacheManager cacheManager() {

148

RedisCacheManager.Builder builder = RedisCacheManager

149

.RedisCacheManagerBuilder

150

.fromConnectionFactory(redisConnectionFactory())

151

.cacheDefaults(cacheConfiguration());

152

return builder.build();

153

}

154

155

@Bean

156

public StatelessTicketCache springCacheBasedTicketCache() {

157

Cache cache = cacheManager().getCache("casTickets");

158

return new SpringCacheBasedTicketCache(cache);

159

}

160

161

private RedisCacheConfiguration cacheConfiguration() {

162

return RedisCacheConfiguration.defaultCacheConfig()

163

.entryTtl(Duration.ofMinutes(5)) // Cache tickets for 5 minutes

164

.serializeKeysWith(RedisSerializationContext.SerializationPair

165

.fromSerializer(new StringRedisSerializer()))

166

.serializeValuesWith(RedisSerializationContext.SerializationPair

167

.fromSerializer(new GenericJackson2JsonRedisSerializer()));

168

}

169

}

170

```

171

172

## Cache Configuration Examples

173

174

### Redis-Based Caching

175

176

```java

177

@Configuration

178

@EnableCaching

179

public class RedisCacheConfig {

180

181

@Bean

182

public LettuceConnectionFactory redisConnectionFactory() {

183

return new LettuceConnectionFactory(

184

new RedisStandaloneConfiguration("localhost", 6379));

185

}

186

187

@Bean

188

public RedisCacheManager cacheManager() {

189

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()

190

.entryTtl(Duration.ofMinutes(10)) // 10-minute TTL

191

.disableCachingNullValues()

192

.serializeKeysWith(RedisSerializationContext.SerializationPair

193

.fromSerializer(new StringRedisSerializer()))

194

.serializeValuesWith(RedisSerializationContext.SerializationPair

195

.fromSerializer(new GenericJackson2JsonRedisSerializer()));

196

197

return RedisCacheManager.builder(redisConnectionFactory())

198

.cacheDefaults(config)

199

.build();

200

}

201

202

@Bean

203

public StatelessTicketCache redisTicketCache() {

204

Cache cache = cacheManager().getCache("cas-tickets");

205

return new SpringCacheBasedTicketCache(cache);

206

}

207

}

208

```

209

210

### Hazelcast-Based Caching

211

212

```java

213

@Configuration

214

@EnableCaching

215

public class HazelcastCacheConfig {

216

217

@Bean

218

public HazelcastInstance hazelcastInstance() {

219

Config config = new Config();

220

config.getMapConfig("cas-tickets")

221

.setTimeToLiveSeconds(300) // 5-minute TTL

222

.setMaxIdleSeconds(300);

223

return Hazelcast.newHazelcastInstance(config);

224

}

225

226

@Bean

227

public CacheManager hazelcastCacheManager() {

228

return new HazelcastCacheManager(hazelcastInstance());

229

}

230

231

@Bean

232

public StatelessTicketCache hazelcastTicketCache() {

233

Cache cache = hazelcastCacheManager().getCache("cas-tickets");

234

return new SpringCacheBasedTicketCache(cache);

235

}

236

}

237

```

238

239

### Ehcache-Based Caching

240

241

```java

242

@Configuration

243

@EnableCaching

244

public class EhcacheConfig {

245

246

@Bean

247

public CacheManager ehCacheManager() {

248

CachingProvider provider = Caching.getCachingProvider();

249

javax.cache.CacheManager cacheManager = provider.getCacheManager();

250

251

javax.cache.configuration.Configuration<String, CasAuthenticationToken> configuration =

252

Eh107Configuration.fromEhcacheCacheConfiguration(

253

CacheConfigurationBuilder

254

.newCacheConfigurationBuilder(String.class, CasAuthenticationToken.class,

255

ResourcePoolsBuilder.heap(1000))

256

.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMinutes(5)))

257

.build());

258

259

cacheManager.createCache("cas-tickets", configuration);

260

return new JCacheCacheManager(cacheManager);

261

}

262

263

@Bean

264

public StatelessTicketCache ehcacheTicketCache() {

265

Cache cache = ehCacheManager().getCache("cas-tickets");

266

return new SpringCacheBasedTicketCache(cache);

267

}

268

}

269

```

270

271

## Cache Integration with Authentication Provider

272

273

```java

274

@Bean

275

public CasAuthenticationProvider casAuthenticationProvider() {

276

CasAuthenticationProvider provider = new CasAuthenticationProvider();

277

provider.setServiceProperties(serviceProperties());

278

provider.setTicketValidator(ticketValidator());

279

provider.setUserDetailsService(userDetailsService());

280

provider.setKey("cas-authentication-provider");

281

282

// Set ticket cache for performance optimization

283

provider.setStatelessTicketCache(springCacheBasedTicketCache());

284

285

return provider;

286

}

287

```

288

289

## Cache Considerations

290

291

### Cache Key Strategy

292

293

The cache uses the CAS service ticket as the key:

294

295

```java

296

// Cache key format

297

String cacheKey = casAuthenticationToken.getCredentials().toString();

298

299

// Example cache key

300

"ST-123456-abcdefghijklmnop-cas-server.example.com"

301

```

302

303

### Cache Expiration

304

305

- **Short TTL**: Tickets should expire quickly to maintain security

306

- **Ticket Lifetime**: Should not exceed CAS server ticket expiration

307

- **Recommended**: 5-10 minutes maximum

308

- **Security**: Shorter expiration reduces risk of ticket replay

309

310

### Serialization Requirements

311

312

Cached objects must be serializable:

313

314

```java

315

// CasAuthenticationToken implements Serializable

316

public class CasAuthenticationToken extends AbstractAuthenticationToken implements Serializable {

317

private static final long serialVersionUID = 1L;

318

// ...

319

}

320

```

321

322

### Performance Benefits

323

324

- **Reduced Network Calls**: Avoids repeated CAS server validation

325

- **Improved Response Time**: Local cache access vs. network round-trip

326

- **Server Load Reduction**: Decreases load on CAS server

327

- **Scalability**: Better performance in high-traffic scenarios

328

329

### Cache Monitoring

330

331

```java

332

@Component

333

public class CacheMetrics {

334

335

@Autowired

336

private CacheManager cacheManager;

337

338

@EventListener

339

public void handleCacheHit(CacheHitEvent event) {

340

// Log or meter cache hits

341

log.debug("Cache hit for ticket: {}", event.getKey());

342

}

343

344

@EventListener

345

public void handleCacheMiss(CacheMissEvent event) {

346

// Log or meter cache misses

347

log.debug("Cache miss for ticket: {}", event.getKey());

348

}

349

}

350

```

351

352

## Security Considerations

353

354

- **Cache Isolation**: Separate cache namespace for CAS tickets

355

- **Access Control**: Restrict cache access to authentication components

356

- **Encryption**: Consider encrypting cached authentication tokens

357

- **Audit Trail**: Log cache operations for security monitoring

358

- **Cleanup**: Ensure proper cache cleanup on logout or session invalidation

359

360

## Best Practices

361

362

1. **Use Distributed Cache**: For clustered applications

363

2. **Short Expiration**: Keep TTL under 10 minutes

364

3. **Monitor Performance**: Track cache hit/miss ratios

365

4. **Secure Configuration**: Encrypt sensitive cache data

366

5. **Proper Sizing**: Configure appropriate cache size limits

367

6. **Exception Handling**: Handle cache failures gracefully