or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcore-adapters.mdhttp-operations.mdindex.mdjaas-integration.mdkey-rotation.mdpolicy-enforcement.mdtoken-storage.mdutility-operations.md

http-operations.mddocs/

0

# HTTP Operations

1

2

HTTP client builder with SSL configuration and server request utilities for token operations, logout, and node registration. This module provides secure HTTP communication capabilities with Keycloak servers and comprehensive request handling utilities.

3

4

## Capabilities

5

6

### HttpClientBuilder

7

8

Builder for creating configured HttpClient instances with SSL support and connection management.

9

10

```java { .api }

11

/**

12

* Builder for creating configured HttpClient instances with SSL support and connection management

13

*/

14

public class HttpClientBuilder {

15

/**

16

* Set socket timeout for HTTP operations

17

* @param timeout Timeout value

18

* @param unit Time unit for timeout

19

* @return Builder instance for chaining

20

*/

21

public HttpClientBuilder socketTimeout(long timeout, TimeUnit unit);

22

23

/**

24

* Set connection establishment timeout

25

* @param timeout Timeout value for connection establishment

26

* @param unit Time unit for timeout

27

* @return Builder instance for chaining

28

*/

29

public HttpClientBuilder establishConnectionTimeout(long timeout, TimeUnit unit);

30

31

/**

32

* Set connection time-to-live

33

* @param ttl Time-to-live value

34

* @param unit Time unit for TTL

35

* @return Builder instance for chaining

36

*/

37

public HttpClientBuilder connectionTTL(long ttl, TimeUnit unit);

38

39

/**

40

* Set maximum connections per route

41

* @param maxPooledPerRoute Maximum connections per route

42

* @return Builder instance for chaining

43

*/

44

public HttpClientBuilder maxPooledPerRoute(int maxPooledPerRoute);

45

46

/**

47

* Set total connection pool size

48

* @param connectionPoolSize Total pool size

49

* @return Builder instance for chaining

50

*/

51

public HttpClientBuilder connectionPoolSize(int connectionPoolSize);

52

53

/**

54

* Disable trust manager (accept all certificates)

55

* WARNING: Only use for development/testing

56

* @return Builder instance for chaining

57

*/

58

public HttpClientBuilder disableTrustManager();

59

60

/**

61

* Configure cookie cache behavior

62

* @param disable Whether to disable cookie caching

63

* @return Builder instance for chaining

64

*/

65

public HttpClientBuilder disableCookieCache(boolean disable);

66

67

/**

68

* Set hostname verification policy

69

* @param policy Hostname verification policy

70

* @return Builder instance for chaining

71

*/

72

public HttpClientBuilder hostnameVerification(HostnameVerificationPolicy policy);

73

74

/**

75

* Set custom SSL context

76

* @param sslContext Configured SSL context

77

* @return Builder instance for chaining

78

*/

79

public HttpClientBuilder sslContext(SSLContext sslContext);

80

81

/**

82

* Set trust store for server certificate validation

83

* @param truststore Trust store containing trusted certificates

84

* @return Builder instance for chaining

85

*/

86

public HttpClientBuilder trustStore(KeyStore truststore);

87

88

/**

89

* Set client key store for mutual TLS

90

* @param keyStore Key store containing client certificate and private key

91

* @param password Key store password

92

* @return Builder instance for chaining

93

*/

94

public HttpClientBuilder keyStore(KeyStore keyStore, String password);

95

96

/**

97

* Set client key store for mutual TLS with char array password

98

* @param keyStore Key store containing client certificate and private key

99

* @param password Key store password as char array

100

* @return Builder instance for chaining

101

*/

102

public HttpClientBuilder keyStore(KeyStore keyStore, char[] password);

103

104

/**

105

* Build HTTP client with default configuration

106

* @return Configured HttpClient instance

107

*/

108

public HttpClient build();

109

110

/**

111

* Build HTTP client with adapter-specific configuration

112

* @param adapterConfig Adapter HTTP client configuration

113

* @return Configured HttpClient instance

114

*/

115

public HttpClient build(AdapterHttpClientConfig adapterConfig);

116

117

/**

118

* Hostname verification policy enumeration

119

*/

120

public enum HostnameVerificationPolicy {

121

/** Accept any hostname (insecure) */

122

ANY,

123

/** Standard wildcard verification */

124

WILDCARD,

125

/** Strict hostname verification */

126

STRICT

127

}

128

}

129

```

130

131

**Usage Examples:**

132

133

```java

134

// Basic HTTP client for Keycloak communication

135

HttpClient client = new HttpClientBuilder()

136

.socketTimeout(30, TimeUnit.SECONDS)

137

.establishConnectionTimeout(10, TimeUnit.SECONDS)

138

.connectionPoolSize(20)

139

.maxPooledPerRoute(5)

140

.build();

141

142

// HTTP client with custom SSL configuration

143

KeyStore trustStore = loadTrustStore();

144

HttpClient secureClient = new HttpClientBuilder()

145

.trustStore(trustStore)

146

.hostnameVerification(HostnameVerificationPolicy.STRICT)

147

.socketTimeout(60, TimeUnit.SECONDS)

148

.build();

149

150

// HTTP client with mutual TLS

151

KeyStore clientKeyStore = loadClientKeyStore();

152

HttpClient mutualTlsClient = new HttpClientBuilder()

153

.keyStore(clientKeyStore, "keystore-password")

154

.trustStore(trustStore)

155

.sslContext(createCustomSslContext())

156

.build();

157

158

// Development/testing client (insecure)

159

HttpClient devClient = new HttpClientBuilder()

160

.disableTrustManager()

161

.hostnameVerification(HostnameVerificationPolicy.ANY)

162

.build();

163

164

// Configure in deployment

165

KeycloakDeployment deployment = new KeycloakDeployment();

166

deployment.setClient(secureClient);

167

```

168

169

### ServerRequest

170

171

Utility class for server-side operations including token management, logout, and node registration.

172

173

```java { .api }

174

/**

175

* Utility class for server-side operations including token management, logout, and node registration

176

*/

177

public class ServerRequest {

178

/**

179

* Exception thrown for HTTP operation failures

180

*/

181

public static class HttpFailure extends Exception {

182

public HttpFailure(String message);

183

public HttpFailure(String message, Throwable cause);

184

}

185

186

/**

187

* Invoke logout on Keycloak server

188

* @param deployment Keycloak deployment configuration

189

* @param refreshToken Refresh token to invalidate

190

* @throws IOException If network operation fails

191

* @throws HttpFailure If server returns error response

192

*/

193

public static void invokeLogout(KeycloakDeployment deployment, String refreshToken)

194

throws IOException, HttpFailure;

195

196

/**

197

* Exchange authorization code for tokens

198

* @param deployment Keycloak deployment configuration

199

* @param code Authorization code from OAuth flow

200

* @param redirectUri Redirect URI used in authorization request

201

* @param sessionId Session identifier

202

* @return Access token response containing tokens

203

* @throws IOException If network operation fails

204

* @throws HttpFailure If server returns error response

205

*/

206

public static AccessTokenResponse invokeAccessCodeToToken(

207

KeycloakDeployment deployment,

208

String code,

209

String redirectUri,

210

String sessionId

211

) throws IOException, HttpFailure;

212

213

/**

214

* Exchange authorization code for tokens with PKCE

215

* @param deployment Keycloak deployment configuration

216

* @param code Authorization code from OAuth flow

217

* @param redirectUri Redirect URI used in authorization request

218

* @param sessionId Session identifier

219

* @param codeVerifier PKCE code verifier

220

* @return Access token response containing tokens

221

* @throws IOException If network operation fails

222

* @throws HttpFailure If server returns error response

223

*/

224

public static AccessTokenResponse invokeAccessCodeToToken(

225

KeycloakDeployment deployment,

226

String code,

227

String redirectUri,

228

String sessionId,

229

String codeVerifier

230

) throws IOException, HttpFailure;

231

232

/**

233

* Refresh access token using refresh token

234

* @param deployment Keycloak deployment configuration

235

* @param refreshToken Current refresh token

236

* @return Access token response with new tokens

237

* @throws IOException If network operation fails

238

* @throws HttpFailure If server returns error response

239

*/

240

public static AccessTokenResponse invokeRefresh(

241

KeycloakDeployment deployment,

242

String refreshToken

243

) throws IOException, HttpFailure;

244

245

/**

246

* Register application node with Keycloak server

247

* @param deployment Keycloak deployment configuration

248

* @param host Host identifier for the node

249

* @throws HttpFailure If registration fails

250

* @throws IOException If network operation fails

251

*/

252

public static void invokeRegisterNode(KeycloakDeployment deployment, String host)

253

throws HttpFailure, IOException;

254

255

/**

256

* Unregister application node from Keycloak server

257

* @param deployment Keycloak deployment configuration

258

* @param host Host identifier for the node

259

* @throws HttpFailure If unregistration fails

260

* @throws IOException If network operation fails

261

*/

262

public static void invokeUnregisterNode(KeycloakDeployment deployment, String host)

263

throws HttpFailure, IOException;

264

265

/**

266

* Invoke generic client management request

267

* @param deployment Keycloak deployment configuration

268

* @param host Host identifier

269

* @param endpointUrl Management endpoint URL

270

* @throws HttpFailure If request fails

271

* @throws IOException If network operation fails

272

*/

273

public static void invokeClientManagementRequest(

274

KeycloakDeployment deployment,

275

String host,

276

String endpointUrl

277

) throws HttpFailure, IOException;

278

279

/**

280

* Handle error response and throw appropriate exception

281

* @param status HTTP status code

282

* @param entity Response entity

283

* @throws HttpFailure Always thrown with error details

284

* @throws IOException If entity processing fails

285

*/

286

public static void error(int status, HttpEntity entity) throws HttpFailure, IOException;

287

}

288

```

289

290

**Usage Examples:**

291

292

```java

293

// Token refresh operation

294

try {

295

AccessTokenResponse tokenResponse = ServerRequest.invokeRefresh(deployment, refreshToken);

296

297

String newAccessToken = tokenResponse.getToken();

298

String newRefreshToken = tokenResponse.getRefreshToken();

299

String newIdToken = tokenResponse.getIdToken();

300

int expiresIn = tokenResponse.getExpiresIn();

301

302

// Update security context with new tokens

303

securityContext.updateTokens(newAccessToken, newRefreshToken, newIdToken);

304

305

} catch (ServerRequest.HttpFailure e) {

306

// Handle server error (e.g., invalid refresh token)

307

logger.warn("Token refresh failed: {}", e.getMessage());

308

// Redirect to re-authentication

309

310

} catch (IOException e) {

311

// Handle network error

312

logger.error("Network error during token refresh", e);

313

// Retry or fallback logic

314

}

315

316

// Authorization code exchange

317

try {

318

AccessTokenResponse tokenResponse = ServerRequest.invokeAccessCodeToToken(

319

deployment,

320

authorizationCode,

321

redirectUri,

322

sessionId

323

);

324

325

// Create security context from tokens

326

RefreshableKeycloakSecurityContext securityContext =

327

createSecurityContext(tokenResponse);

328

329

} catch (ServerRequest.HttpFailure e) {

330

// Handle authorization code exchange failure

331

logger.warn("Code to token exchange failed: {}", e.getMessage());

332

sendOAuthError(response, "invalid_grant", e.getMessage());

333

}

334

335

// PKCE-enabled authorization code exchange

336

String codeVerifier = generateCodeVerifier();

337

try {

338

AccessTokenResponse tokenResponse = ServerRequest.invokeAccessCodeToToken(

339

deployment,

340

authorizationCode,

341

redirectUri,

342

sessionId,

343

codeVerifier

344

);

345

346

} catch (ServerRequest.HttpFailure e) {

347

logger.warn("PKCE code exchange failed: {}", e.getMessage());

348

}

349

350

// User logout

351

try {

352

ServerRequest.invokeLogout(deployment, refreshToken);

353

logger.debug("User logged out successfully");

354

355

} catch (ServerRequest.HttpFailure e) {

356

logger.warn("Logout request failed: {}", e.getMessage());

357

// Continue with local logout even if server logout fails

358

359

} catch (IOException e) {

360

logger.error("Network error during logout", e);

361

}

362

363

// Node registration for clustered applications

364

try {

365

String hostIdentifier = InetAddress.getLocalHost().getHostName();

366

ServerRequest.invokeRegisterNode(deployment, hostIdentifier);

367

logger.info("Node registered with Keycloak: {}", hostIdentifier);

368

369

} catch (ServerRequest.HttpFailure e) {

370

logger.error("Failed to register node: {}", e.getMessage());

371

372

} catch (IOException e) {

373

logger.error("Network error during node registration", e);

374

}

375

376

// Node unregistration during shutdown

377

Runtime.getRuntime().addShutdownHook(new Thread(() -> {

378

try {

379

String hostIdentifier = getCurrentHostIdentifier();

380

ServerRequest.invokeUnregisterNode(deployment, hostIdentifier);

381

logger.info("Node unregistered from Keycloak: {}", hostIdentifier);

382

} catch (Exception e) {

383

logger.warn("Failed to unregister node during shutdown", e);

384

}

385

}));

386

```

387

388

### HttpClientAdapterException

389

390

Exception thrown for HTTP client adapter operations.

391

392

```java { .api }

393

/**

394

* Exception thrown for HTTP client adapter operations

395

*/

396

public class HttpClientAdapterException extends Exception {

397

/**

398

* Constructor with error message

399

* @param message Error description

400

*/

401

public HttpClientAdapterException(String message);

402

403

/**

404

* Constructor with error message and cause

405

* @param message Error description

406

* @param t Underlying cause

407

*/

408

public HttpClientAdapterException(String message, Throwable t);

409

}

410

```

411

412

**Usage Examples:**

413

414

```java

415

// Exception handling in HTTP operations

416

public void performKeycloakRequest(KeycloakDeployment deployment) {

417

try {

418

HttpClient client = deployment.getClient();

419

HttpGet request = new HttpGet(deployment.getRealmInfoUrl());

420

421

HttpResponse response = client.execute(request);

422

if (response.getStatusLine().getStatusCode() != 200) {

423

throw new HttpClientAdapterException(

424

"Failed to fetch realm info: " + response.getStatusLine().getReasonPhrase()

425

);

426

}

427

428

// Process successful response

429

430

} catch (IOException e) {

431

throw new HttpClientAdapterException("Network error accessing Keycloak", e);

432

} catch (Exception e) {

433

throw new HttpClientAdapterException("Unexpected error in Keycloak request", e);

434

}

435

}

436

```

437

438

## HTTP Configuration Patterns

439

440

### SSL Configuration

441

442

```java

443

// Custom SSL context with specific trust store

444

public SSLContext createCustomSslContext() throws Exception {

445

// Load custom trust store

446

KeyStore trustStore = KeyStore.getInstance("JKS");

447

try (InputStream trustStoreStream = getClass().getResourceAsStream("/keycloak-truststore.jks")) {

448

trustStore.load(trustStoreStream, "truststore-password".toCharArray());

449

}

450

451

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

452

tmf.init(trustStore);

453

454

SSLContext sslContext = SSLContext.getInstance("TLS");

455

sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());

456

457

return sslContext;

458

}

459

460

// Configure deployment with custom SSL

461

KeycloakDeployment deployment = new KeycloakDeployment();

462

HttpClient client = new HttpClientBuilder()

463

.sslContext(createCustomSslContext())

464

.hostnameVerification(HostnameVerificationPolicy.STRICT)

465

.build();

466

deployment.setClient(client);

467

```

468

469

### Connection Pool Configuration

470

471

```java

472

// Production HTTP client configuration

473

public HttpClient createProductionHttpClient() {

474

return new HttpClientBuilder()

475

.connectionPoolSize(50) // Total connections

476

.maxPooledPerRoute(10) // Per-route connections

477

.connectionTTL(60, TimeUnit.SECONDS) // Connection reuse time

478

.socketTimeout(30, TimeUnit.SECONDS) // Response timeout

479

.establishConnectionTimeout(10, TimeUnit.SECONDS) // Connection timeout

480

.build();

481

}

482

483

// Development HTTP client configuration

484

public HttpClient createDevelopmentHttpClient() {

485

return new HttpClientBuilder()

486

.disableTrustManager() // Accept self-signed certificates

487

.hostnameVerification(HostnameVerificationPolicy.ANY)

488

.socketTimeout(60, TimeUnit.SECONDS) // Longer timeout for debugging

489

.build();

490

}

491

```