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

authentication.mddocs/

0

# Authentication

1

2

Authentication flow handling with support for bearer tokens, basic authentication, and OAuth flows. This module provides comprehensive authentication mechanisms and security context management with token refresh capabilities.

3

4

## Capabilities

5

6

### RequestAuthenticator

7

8

Base abstract class for request authentication providing common authentication flow logic.

9

10

```java { .api }

11

/**

12

* Base abstract class for request authentication

13

*/

14

public abstract class RequestAuthenticator {

15

/**

16

* Constructor for request authenticator with SSL redirect port

17

* @param facade HTTP facade for request/response handling

18

* @param deployment Keycloak deployment configuration

19

* @param tokenStore Token storage implementation

20

* @param sslRedirectPort Port for SSL redirects

21

*/

22

public RequestAuthenticator(

23

HttpFacade facade,

24

KeycloakDeployment deployment,

25

AdapterTokenStore tokenStore,

26

int sslRedirectPort

27

);

28

29

/**

30

* Constructor for request authenticator without SSL redirect

31

* @param facade HTTP facade for request/response handling

32

* @param deployment Keycloak deployment configuration

33

*/

34

public RequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment);

35

36

/**

37

* Get authentication challenge for unauthenticated requests

38

* @return AuthChallenge instance or null if no challenge needed

39

*/

40

public AuthChallenge getChallenge();

41

42

/**

43

* Perform authentication for the current request

44

* @return AuthOutcome indicating authentication result

45

*/

46

public AuthOutcome authenticate();

47

48

// Protected methods for subclass implementation

49

protected abstract OAuthRequestAuthenticator createOAuthAuthenticator();

50

protected BearerTokenRequestAuthenticator createBearerTokenAuthenticator();

51

protected BasicAuthRequestAuthenticator createBasicAuthAuthenticator();

52

protected QueryParameterTokenRequestAuthenticator createQueryParameterTokenRequestAuthenticator();

53

protected abstract void completeOAuthAuthentication(KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal);

54

protected abstract void completeBearerAuthentication(KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal, String method);

55

protected abstract String changeHttpSessionId(boolean create);

56

}

57

```

58

59

### BearerTokenRequestAuthenticator

60

61

Authenticator for bearer token validation in API requests.

62

63

```java { .api }

64

/**

65

* Authenticator for bearer token validation in API requests

66

*/

67

public class BearerTokenRequestAuthenticator {

68

/**

69

* Constructor for bearer token authenticator

70

* @param deployment Keycloak deployment configuration

71

*/

72

public BearerTokenRequestAuthenticator(KeycloakDeployment deployment);

73

74

/**

75

* Get authentication challenge for bearer token requests

76

* @return AuthChallenge for WWW-Authenticate header

77

*/

78

public AuthChallenge getChallenge();

79

80

/**

81

* Get the raw token string from the request

82

* @return Bearer token string or null if not present

83

*/

84

public String getTokenString();

85

86

/**

87

* Get the parsed and validated access token

88

* @return AccessToken instance or null if validation failed

89

*/

90

public AccessToken getToken();

91

92

/**

93

* Get the surrogate authentication user

94

* @return Surrogate user identifier or null

95

*/

96

public String getSurrogate();

97

98

/**

99

* Authenticate the bearer token request

100

* @param exchange HTTP exchange containing the request

101

* @return AuthOutcome indicating authentication result

102

*/

103

public AuthOutcome authenticate(HttpFacade exchange);

104

}

105

```

106

107

**Usage Examples:**

108

109

```java

110

// Bearer token authentication

111

BearerTokenRequestAuthenticator bearerAuth = new BearerTokenRequestAuthenticator(deployment);

112

AuthOutcome outcome = bearerAuth.authenticate(httpFacade);

113

114

if (outcome == AuthOutcome.AUTHENTICATED) {

115

AccessToken token = bearerAuth.getToken();

116

String tokenString = bearerAuth.getTokenString();

117

118

// Extract user information

119

String username = token.getPreferredUsername();

120

Set<String> roles = token.getRealmAccess().getRoles();

121

122

// Use token for authorization decisions

123

if (roles.contains("admin")) {

124

// Allow admin operations

125

}

126

} else if (outcome == AuthOutcome.FAILED) {

127

AuthChallenge challenge = bearerAuth.getChallenge();

128

// Send challenge response

129

}

130

```

131

132

### BasicAuthRequestAuthenticator

133

134

Authenticator for HTTP Basic Authentication with Keycloak credentials.

135

136

```java { .api }

137

/**

138

* Authenticator for HTTP Basic Authentication with Keycloak credentials

139

*/

140

public class BasicAuthRequestAuthenticator {

141

/**

142

* Constructor for basic auth authenticator

143

* @param deployment Keycloak deployment configuration

144

*/

145

public BasicAuthRequestAuthenticator(KeycloakDeployment deployment);

146

147

/**

148

* Authenticate using HTTP Basic Authentication

149

* @param exchange HTTP exchange containing credentials

150

* @return AuthOutcome indicating authentication result

151

*/

152

public AuthOutcome authenticate(HttpFacade exchange);

153

}

154

```

155

156

**Usage Examples:**

157

158

```java

159

// Basic authentication

160

BasicAuthRequestAuthenticator basicAuth = new BasicAuthRequestAuthenticator(deployment);

161

AuthOutcome outcome = basicAuth.authenticate(httpFacade);

162

163

if (outcome == AuthOutcome.AUTHENTICATED) {

164

// User authenticated via basic auth

165

// Continue with request processing

166

} else {

167

// Send 401 Unauthorized with WWW-Authenticate header

168

httpFacade.getResponse().setStatus(401);

169

httpFacade.getResponse().setHeader("WWW-Authenticate", "Basic realm=\"keycloak\"");

170

}

171

```

172

173

### RefreshableKeycloakSecurityContext

174

175

Security context providing access to tokens with automatic refresh capabilities.

176

177

```java { .api }

178

/**

179

* Security context providing access to tokens with automatic refresh capabilities

180

*/

181

public class RefreshableKeycloakSecurityContext extends KeycloakSecurityContext {

182

/**

183

* Default constructor

184

*/

185

public RefreshableKeycloakSecurityContext();

186

187

/**

188

* Constructor with complete token set

189

* @param deployment Keycloak deployment configuration

190

* @param tokenStore Token storage implementation

191

* @param tokenString Raw access token string

192

* @param token Parsed access token

193

* @param idTokenString Raw ID token string

194

* @param idToken Parsed ID token

195

* @param refreshToken Refresh token string

196

*/

197

public RefreshableKeycloakSecurityContext(

198

KeycloakDeployment deployment,

199

AdapterTokenStore tokenStore,

200

String tokenString,

201

AccessToken token,

202

String idTokenString,

203

IDToken idToken,

204

String refreshToken

205

);

206

207

/**

208

* Get the current access token

209

* @return AccessToken instance

210

*/

211

public AccessToken getToken();

212

213

/**

214

* Get the raw access token string

215

* @return Access token as string

216

*/

217

public String getTokenString();

218

219

/**

220

* Get the current ID token

221

* @return IDToken instance

222

*/

223

public IDToken getIdToken();

224

225

/**

226

* Get the raw ID token string

227

* @return ID token as string

228

*/

229

public String getIdTokenString();

230

231

/**

232

* Get the refresh token

233

* @return Refresh token string

234

*/

235

public String getRefreshToken();

236

237

/**

238

* Logout the current session

239

* @param deployment Keycloak deployment configuration

240

*/

241

public void logout(KeycloakDeployment deployment);

242

243

/**

244

* Check if the security context is active

245

* @return true if tokens are valid and not expired

246

*/

247

public boolean isActive();

248

249

/**

250

* Check if token has sufficient time to live

251

* @param token Token to check

252

* @return true if token has sufficient TTL

253

*/

254

public boolean isTokenTimeToLiveSufficient(AccessToken token);

255

256

/**

257

* Get the deployment configuration

258

* @return KeycloakDeployment instance

259

*/

260

public KeycloakDeployment getDeployment();

261

262

/**

263

* Set current request information for token refresh

264

* @param deployment Keycloak deployment configuration

265

* @param tokenStore Token storage implementation

266

*/

267

public void setCurrentRequestInfo(KeycloakDeployment deployment, AdapterTokenStore tokenStore);

268

269

/**

270

* Refresh expired tokens

271

* @param checkActive Whether to check if context is active first

272

* @return true if refresh was successful

273

*/

274

public boolean refreshExpiredToken(boolean checkActive);

275

276

/**

277

* Set authorization context for policy enforcement

278

* @param authorizationContext Authorization context instance

279

*/

280

public void setAuthorizationContext(AuthorizationContext authorizationContext);

281

}

282

```

283

284

**Usage Examples:**

285

286

```java

287

// Create security context from tokens

288

RefreshableKeycloakSecurityContext securityContext = new RefreshableKeycloakSecurityContext(

289

deployment, tokenStore, tokenString, accessToken, idTokenString, idToken, refreshToken

290

);

291

292

// Check if context is active

293

if (securityContext.isActive()) {

294

AccessToken token = securityContext.getToken();

295

296

// Check if token needs refresh

297

if (!securityContext.isTokenTimeToLiveSufficient(token)) {

298

// Attempt to refresh token

299

boolean refreshed = securityContext.refreshExpiredToken(true);

300

if (refreshed) {

301

// Use refreshed token

302

token = securityContext.getToken();

303

}

304

}

305

306

// Access user information

307

String username = token.getPreferredUsername();

308

String email = token.getEmail();

309

Map<String, Object> customClaims = token.getOtherClaims();

310

}

311

312

// Logout when done

313

securityContext.logout(deployment);

314

```

315

316

### QueryParameterTokenRequestAuthenticator

317

318

Authenticator for extracting bearer tokens from URL query parameters instead of Authorization header.

319

320

```java { .api }

321

/**

322

* Authenticator for extracting bearer tokens from URL query parameters

323

*/

324

public class QueryParameterTokenRequestAuthenticator {

325

/**

326

* Constructor for query parameter token authenticator

327

* @param deployment Keycloak deployment configuration

328

*/

329

public QueryParameterTokenRequestAuthenticator(KeycloakDeployment deployment);

330

331

/**

332

* Get authentication challenge for query parameter token requests

333

* @return AuthChallenge for error responses

334

*/

335

public AuthChallenge getChallenge();

336

337

/**

338

* Get the raw token string from query parameters

339

* @return Bearer token string or null if not present

340

*/

341

public String getTokenString();

342

343

/**

344

* Get the parsed and validated access token

345

* @return AccessToken instance or null if validation failed

346

*/

347

public AccessToken getToken();

348

349

/**

350

* Authenticate the request using query parameter token

351

* @param exchange HTTP exchange containing the request

352

* @return AuthOutcome indicating authentication result

353

*/

354

public AuthOutcome authenticate(HttpFacade exchange);

355

}

356

```

357

358

**Usage Examples:**

359

360

```java

361

// Query parameter token authentication (e.g., for WebSocket connections)

362

QueryParameterTokenRequestAuthenticator queryAuth =

363

new QueryParameterTokenRequestAuthenticator(deployment);

364

365

AuthOutcome outcome = queryAuth.authenticate(httpFacade);

366

367

if (outcome == AuthOutcome.AUTHENTICATED) {

368

AccessToken token = queryAuth.getToken();

369

String tokenString = queryAuth.getTokenString();

370

371

// Token was successfully extracted from query parameter

372

// e.g., /api/websocket?access_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

373

String username = token.getPreferredUsername();

374

375

} else if (outcome == AuthOutcome.FAILED) {

376

AuthChallenge challenge = queryAuth.getChallenge();

377

// Handle authentication failure

378

}

379

```

380

381

### AuthenticatedActionsHandler

382

383

Handler for pre-authenticated actions like CORS preflight and bearer token queries.

384

385

```java { .api }

386

/**

387

* Handler for pre-authenticated actions like CORS preflight and bearer token queries

388

*/

389

public class AuthenticatedActionsHandler {

390

/**

391

* Constructor for authenticated actions handler

392

* @param deployment Keycloak deployment configuration

393

* @param facade OIDC HTTP facade

394

*/

395

public AuthenticatedActionsHandler(KeycloakDeployment deployment, OIDCHttpFacade facade);

396

397

/**

398

* Handle the request if it matches a pre-authenticated action

399

* @return true if request was handled, false otherwise

400

*/

401

public boolean handledRequest();

402

}

403

```

404

405

**Usage Examples:**

406

407

```java

408

// Handle pre-authenticated actions

409

AuthenticatedActionsHandler actionsHandler =

410

new AuthenticatedActionsHandler(deployment, oidcFacade);

411

412

if (actionsHandler.handledRequest()) {

413

// Request was handled (e.g., CORS preflight)

414

// No further processing needed

415

return;

416

}

417

418

// Continue with normal authentication flow

419

RequestAuthenticator authenticator = createAuthenticator(facade, deployment);

420

AuthOutcome outcome = authenticator.authenticate();

421

```

422

423

### OidcKeycloakAccount

424

425

Interface representing an authenticated OIDC account.

426

427

```java { .api }

428

/**

429

* Interface representing an authenticated OIDC account

430

*/

431

public interface OidcKeycloakAccount extends KeycloakAccount {

432

/**

433

* Get the security context for this account

434

* @return KeycloakSecurityContext instance

435

*/

436

KeycloakSecurityContext getKeycloakSecurityContext();

437

}

438

```

439

440

### OIDCHttpFacade

441

442

HTTP facade interface for OIDC operations.

443

444

```java { .api }

445

/**

446

* HTTP facade interface for OIDC operations extending base HttpFacade

447

*/

448

public interface OIDCHttpFacade extends HttpFacade {

449

/**

450

* Get the security context for the current request

451

* @return KeycloakSecurityContext or null if not authenticated

452

*/

453

KeycloakSecurityContext getSecurityContext();

454

}

455

```

456

457

### OIDCAuthenticationError

458

459

Error representation for OIDC authentication failures.

460

461

```java { .api }

462

/**

463

* Error representation for OIDC authentication failures

464

*/

465

public class OIDCAuthenticationError {

466

/**

467

* Enumeration of possible authentication error reasons

468

*/

469

public enum Reason {

470

NO_BEARER_TOKEN,

471

NO_REDIRECT_URI,

472

INVALID_STATE_COOKIE,

473

OAUTH_ERROR,

474

SSL_REQUIRED,

475

CODE_TO_TOKEN_FAILURE,

476

INVALID_TOKEN,

477

STALE_TOKEN,

478

NO_AUTHORIZATION_HEADER,

479

NO_QUERY_PARAMETER_ACCESS_TOKEN

480

}

481

482

/**

483

* Constructor for authentication error

484

* @param reason Error reason from enum

485

* @param description Detailed error description

486

*/

487

public OIDCAuthenticationError(Reason reason, String description);

488

489

/**

490

* Get the error reason

491

* @return Reason enum value

492

*/

493

public Reason getReason();

494

495

/**

496

* Get the error description

497

* @return Detailed error message

498

*/

499

public String getDescription();

500

501

/**

502

* String representation of the error

503

* @return Formatted error string

504

*/

505

public String toString();

506

}

507

```

508

509

**Usage Examples:**

510

511

```java

512

// Handle authentication errors

513

try {

514

AuthOutcome outcome = authenticator.authenticate();

515

if (outcome == AuthOutcome.FAILED) {

516

// Create error for client

517

OIDCAuthenticationError error = new OIDCAuthenticationError(

518

OIDCAuthenticationError.Reason.INVALID_TOKEN,

519

"Token signature validation failed"

520

);

521

522

// Log error details

523

logger.warn("Authentication failed: {} - {}",

524

error.getReason(), error.getDescription());

525

526

// Return appropriate HTTP response

527

sendErrorResponse(error);

528

}

529

} catch (Exception e) {

530

OIDCAuthenticationError error = new OIDCAuthenticationError(

531

OIDCAuthenticationError.Reason.CODE_TO_TOKEN_FAILURE,

532

"Failed to exchange authorization code for tokens: " + e.getMessage()

533

);

534

handleAuthenticationError(error);

535

}

536

```