or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdauthorization.mdexceptions.mdindex.md

authentication.mddocs/

0

# Authentication Context

1

2

The authentication context components provide thread-local user identification and authentication details for authorization requests in the CDAP security framework.

3

4

## Core Authentication Interfaces

5

6

### AuthenticationContext

7

8

Interface for determining authentication details in authorization contexts.

9

10

```java { .api }

11

interface AuthenticationContext {

12

/**

13

* Get the Principal making the current authorization request.

14

*

15

* @return the Principal making the authorization request

16

*/

17

Principal getPrincipal();

18

}

19

```

20

21

## Security Request Context

22

23

### SecurityRequestContext

24

25

Thread-local context for maintaining authenticated user information across request processing.

26

27

```java { .api }

28

final class SecurityRequestContext {

29

/**

30

* Get the user ID set on the current thread.

31

*

32

* @return the user ID or null if not set

33

*/

34

@Nullable

35

static String getUserId();

36

37

/**

38

* Get the user IP address set on the current thread.

39

*

40

* @return the user IP or null if not set

41

*/

42

@Nullable

43

static String getUserIP();

44

45

/**

46

* Set the user ID on the current thread.

47

*

48

* @param userIdParam the user ID to set

49

*/

50

static void setUserId(String userIdParam);

51

52

/**

53

* Set the user IP address on the current thread.

54

*

55

* @param userIPParam the user IP to set

56

*/

57

static void setUserIP(String userIPParam);

58

59

/**

60

* Create a Principal for the user set on the current thread.

61

*

62

* @return Principal with USER type for the current thread's user ID

63

*/

64

static Principal toPrincipal();

65

}

66

```

67

68

## Usage Examples

69

70

### Setting Request Context

71

72

```java

73

import co.cask.cdap.security.spi.authentication.SecurityRequestContext;

74

75

// At the beginning of request processing

76

public void handleRequest(HttpServletRequest request) {

77

// Extract user information from request (e.g., JWT token, session, etc.)

78

String userId = extractUserFromToken(request.getHeader("Authorization"));

79

String clientIP = request.getRemoteAddr();

80

81

// Set context for current thread

82

SecurityRequestContext.setUserId(userId);

83

SecurityRequestContext.setUserIP(clientIP);

84

85

try {

86

// Process request - authorization checks can now access user context

87

processBusinessLogic();

88

} finally {

89

// Clean up thread-local variables to prevent memory leaks

90

SecurityRequestContext.setUserId(null);

91

SecurityRequestContext.setUserIP(null);

92

}

93

}

94

```

95

96

### Using Authentication Context in Authorizers

97

98

```java

99

public class CustomAuthorizer extends AbstractAuthorizer {

100

101

@Override

102

public void initialize(AuthorizationContext context) throws Exception {

103

// AuthorizationContext extends AuthenticationContext

104

// You can get the current principal during initialization if needed

105

Principal currentPrincipal = context.getPrincipal();

106

107

// Initialize your authorization backend

108

setupAuthorizationBackend();

109

}

110

111

@Override

112

public void enforce(EntityId entity, Principal principal, Set<Action> actions)

113

throws Exception {

114

// The principal parameter contains the user information

115

// Additional context can be obtained from SecurityRequestContext if needed

116

String userIP = SecurityRequestContext.getUserIP();

117

118

// Log authorization attempt with IP for auditing

119

auditLog.info("Authorization check for user {} from IP {} on entity {} for actions {}",

120

principal.getName(), userIP, entity, actions);

121

122

// Perform authorization logic

123

if (!isAuthorized(entity, principal, actions)) {

124

throw new UnauthorizedException(principal, actions, entity);

125

}

126

}

127

}

128

```

129

130

### Thread-Safe Context Management

131

132

```java

133

public class RequestProcessor {

134

135

public void processMultipleRequests(List<UserRequest> requests) {

136

// Process requests in parallel, each with its own thread context

137

requests.parallelStream().forEach(this::processRequest);

138

}

139

140

private void processRequest(UserRequest request) {

141

// Each thread gets its own SecurityRequestContext

142

SecurityRequestContext.setUserId(request.getUserId());

143

SecurityRequestContext.setUserIP(request.getClientIP());

144

145

try {

146

// Process request - context is isolated per thread

147

Principal principal = SecurityRequestContext.toPrincipal();

148

authorizer.enforce(request.getTargetEntity(), principal, request.getActions());

149

150

// Perform business logic

151

executeBusinessLogic(request);

152

153

} catch (UnauthorizedException e) {

154

handleUnauthorizedAccess(request, e);

155

} finally {

156

// Clean up to prevent memory leaks

157

clearSecurityContext();

158

}

159

}

160

161

private void clearSecurityContext() {

162

SecurityRequestContext.setUserId(null);

163

SecurityRequestContext.setUserIP(null);

164

}

165

}

166

```

167

168

### Integration with Web Filters

169

170

```java

171

public class SecurityContextFilter implements Filter {

172

173

@Override

174

public void doFilter(ServletRequest request, ServletResponse response,

175

FilterChain chain) throws IOException, ServletException {

176

177

HttpServletRequest httpRequest = (HttpServletRequest) request;

178

179

try {

180

// Extract authentication information

181

String authHeader = httpRequest.getHeader("Authorization");

182

if (authHeader != null && authHeader.startsWith("Bearer ")) {

183

String token = authHeader.substring(7);

184

UserInfo userInfo = validateToken(token);

185

186

// Set security context for downstream processing

187

SecurityRequestContext.setUserId(userInfo.getUserId());

188

SecurityRequestContext.setUserIP(httpRequest.getRemoteAddr());

189

}

190

191

// Continue with request processing

192

chain.doFilter(request, response);

193

194

} finally {

195

// Always clean up thread-local state

196

SecurityRequestContext.setUserId(null);

197

SecurityRequestContext.setUserIP(null);

198

}

199

}

200

201

private UserInfo validateToken(String token) {

202

// Token validation logic

203

return jwtValidator.validate(token);

204

}

205

}

206

```

207

208

### Custom Authentication Context Implementation

209

210

```java

211

public class EnhancedAuthenticationContext implements AuthenticationContext {

212

213

@Override

214

public Principal getPrincipal() {

215

// Use SecurityRequestContext to build Principal

216

String userId = SecurityRequestContext.getUserId();

217

if (userId == null) {

218

throw new IllegalStateException("No user context available");

219

}

220

221

return new Principal(userId, Principal.PrincipalType.USER);

222

}

223

224

/**

225

* Additional method for enhanced context information.

226

*/

227

public String getClientIP() {

228

return SecurityRequestContext.getUserIP();

229

}

230

231

/**

232

* Check if the current request has authentication context.

233

*/

234

public boolean hasAuthenticationContext() {

235

return SecurityRequestContext.getUserId() != null;

236

}

237

}

238

```

239

240

## Integration Patterns

241

242

### With Spring Security

243

244

```java

245

@Component

246

public class SpringSecurityContextAdapter {

247

248

public void setSecurityContextFromSpring() {

249

Authentication auth = SecurityContextHolder.getContext().getAuthentication();

250

if (auth != null && auth.isAuthenticated()) {

251

String username = auth.getName();

252

SecurityRequestContext.setUserId(username);

253

254

// Extract IP from request attributes if available

255

RequestAttributes attributes = RequestContextHolder.getRequestAttributes();

256

if (attributes instanceof ServletRequestAttributes) {

257

HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();

258

SecurityRequestContext.setUserIP(request.getRemoteAddr());

259

}

260

}

261

}

262

263

@PreDestroy

264

public void clearContext() {

265

SecurityRequestContext.setUserId(null);

266

SecurityRequestContext.setUserIP(null);

267

}

268

}

269

```

270

271

### With OAuth/JWT

272

273

```java

274

public class JwtAuthenticationHandler {

275

private final JwtDecoder jwtDecoder;

276

277

public void handleJwtAuthentication(String jwtToken, String clientIP) {

278

try {

279

Jwt jwt = jwtDecoder.decode(jwtToken);

280

281

String userId = jwt.getClaimAsString("sub");

282

String email = jwt.getClaimAsString("email");

283

284

// Use email as user ID if sub is not human-readable

285

SecurityRequestContext.setUserId(email != null ? email : userId);

286

SecurityRequestContext.setUserIP(clientIP);

287

288

} catch (JwtException e) {

289

throw new UnauthorizedException("Invalid JWT token");

290

}

291

}

292

}