or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdauthorities.mdcontext-management.mdembedded-server.mdindex.mdjson-serialization.mdpassword-policy.mduser-details.md

json-serialization.mddocs/

0

# JSON Serialization Support

1

2

Jackson JSON serialization support for Spring Security LDAP classes enabling serialization and deserialization of LDAP user details and authorities.

3

4

## Capabilities

5

6

### LdapJackson2Module

7

8

Jackson module providing serialization support for Spring Security LDAP classes.

9

10

```java { .api }

11

/**

12

* Jackson module that provides serialization support for Spring Security LDAP classes

13

*/

14

public class LdapJackson2Module extends SimpleModule {

15

/**

16

* Creates the LDAP Jackson module with default configuration

17

*/

18

public LdapJackson2Module();

19

20

/**

21

* Sets up the module with mixins for LDAP classes

22

* @param context the setup context

23

*/

24

@Override

25

public void setupModule(SetupContext context);

26

}

27

```

28

29

### Jackson Mixins

30

31

Mixin classes providing JSON serialization configuration for LDAP objects.

32

33

```java { .api }

34

/**

35

* Jackson mixin for LdapUserDetailsImpl serialization

36

*/

37

public abstract class LdapUserDetailsImplMixin {

38

@JsonCreator

39

LdapUserDetailsImplMixin(@JsonProperty("dn") String dn,

40

@JsonProperty("username") String username,

41

@JsonProperty("password") String password,

42

@JsonProperty("enabled") boolean enabled,

43

@JsonProperty("accountNonExpired") boolean accountNonExpired,

44

@JsonProperty("credentialsNonExpired") boolean credentialsNonExpired,

45

@JsonProperty("accountNonLocked") boolean accountNonLocked,

46

@JsonProperty("authorities") Collection<? extends GrantedAuthority> authorities);

47

48

@JsonIgnore

49

abstract Attributes getAttributes();

50

}

51

52

/**

53

* Jackson mixin for Person serialization

54

*/

55

public abstract class PersonMixin {

56

@JsonCreator

57

PersonMixin(@JsonProperty("dn") String dn,

58

@JsonProperty("cn") String cn,

59

@JsonProperty("sn") String sn);

60

61

@JsonProperty

62

abstract String getCn();

63

64

@JsonProperty

65

abstract String getSn();

66

67

@JsonProperty

68

abstract String getDescription();

69

70

@JsonProperty

71

abstract String getTelephoneNumber();

72

}

73

74

/**

75

* Jackson mixin for InetOrgPerson serialization

76

*/

77

public abstract class InetOrgPersonMixin extends PersonMixin {

78

@JsonCreator

79

InetOrgPersonMixin(@JsonProperty("dn") String dn,

80

@JsonProperty("cn") String cn,

81

@JsonProperty("sn") String sn);

82

83

@JsonProperty

84

abstract String getMail();

85

86

@JsonProperty

87

abstract String getEmployeeNumber();

88

89

@JsonProperty

90

abstract String getDisplayName();

91

92

@JsonProperty

93

abstract String getDepartmentNumber();

94

95

@JsonProperty

96

abstract String getCarLicense();

97

98

@JsonProperty

99

abstract String getHomePhone();

100

}

101

102

/**

103

* Jackson mixin for LdapAuthority serialization

104

*/

105

public abstract class LdapAuthorityMixin {

106

@JsonCreator

107

LdapAuthorityMixin(@JsonProperty("role") String role,

108

@JsonProperty("dn") String dn);

109

110

@JsonProperty

111

abstract String getAuthority();

112

113

@JsonProperty

114

abstract String getDn();

115

}

116

```

117

118

## Usage Examples

119

120

### Basic Module Registration

121

122

```java

123

@Configuration

124

public class JacksonConfig {

125

126

@Bean

127

@Primary

128

public ObjectMapper objectMapper() {

129

ObjectMapper mapper = new ObjectMapper();

130

mapper.registerModule(new LdapJackson2Module());

131

return mapper;

132

}

133

}

134

```

135

136

### Serialization Example

137

138

```java

139

@Service

140

public class LdapUserSerializationService {

141

142

private final ObjectMapper objectMapper;

143

144

public LdapUserSerializationService(ObjectMapper objectMapper) {

145

this.objectMapper = objectMapper;

146

}

147

148

public String serializeUser(LdapUserDetails user) throws JsonProcessingException {

149

return objectMapper.writeValueAsString(user);

150

}

151

152

public LdapUserDetails deserializeUser(String json) throws JsonProcessingException {

153

return objectMapper.readValue(json, LdapUserDetailsImpl.class);

154

}

155

156

public String serializePerson(Person person) throws JsonProcessingException {

157

return objectMapper.writeValueAsString(person);

158

}

159

160

public Person deserializePerson(String json) throws JsonProcessingException {

161

return objectMapper.readValue(json, Person.class);

162

}

163

}

164

```

165

166

### Spring Boot Auto-Configuration

167

168

```java

169

@Configuration

170

@ConditionalOnClass({ObjectMapper.class, LdapUserDetails.class})

171

public class LdapJacksonAutoConfiguration {

172

173

@Bean

174

@ConditionalOnMissingBean

175

public LdapJackson2Module ldapJackson2Module() {

176

return new LdapJackson2Module();

177

}

178

179

@Bean

180

@Primary

181

public ObjectMapper ldapObjectMapper(LdapJackson2Module ldapModule) {

182

return JsonMapper.builder()

183

.addModule(ldapModule)

184

.build();

185

}

186

}

187

```

188

189

### Custom Serialization Configuration

190

191

```java

192

@Configuration

193

public class CustomLdapSerializationConfig {

194

195

@Bean

196

public ObjectMapper customLdapMapper() {

197

ObjectMapper mapper = new ObjectMapper();

198

199

// Register LDAP module

200

mapper.registerModule(new LdapJackson2Module());

201

202

// Custom configuration

203

mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

204

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

205

206

// Custom mixins for additional classes

207

mapper.addMixIn(CustomLdapUser.class, CustomLdapUserMixin.class);

208

209

return mapper;

210

}

211

}

212

213

// Example custom mixin

214

abstract class CustomLdapUserMixin {

215

@JsonCreator

216

CustomLdapUserMixin(@JsonProperty("username") String username,

217

@JsonProperty("department") String department,

218

@JsonProperty("manager") String manager);

219

220

@JsonProperty("dept")

221

abstract String getDepartment();

222

223

@JsonIgnore

224

abstract String getInternalId();

225

}

226

```

227

228

### REST Controller Integration

229

230

```java

231

@RestController

232

@RequestMapping("/api/ldap")

233

public class LdapUserController {

234

235

private final LdapUserDetailsService userDetailsService;

236

private final ObjectMapper objectMapper;

237

238

public LdapUserController(LdapUserDetailsService userDetailsService,

239

ObjectMapper objectMapper) {

240

this.userDetailsService = userDetailsService;

241

this.objectMapper = objectMapper;

242

}

243

244

@GetMapping("/users/{username}")

245

public ResponseEntity<String> getUser(@PathVariable String username) {

246

try {

247

UserDetails user = userDetailsService.loadUserByUsername(username);

248

String json = objectMapper.writeValueAsString(user);

249

return ResponseEntity.ok(json);

250

} catch (UsernameNotFoundException e) {

251

return ResponseEntity.notFound().build();

252

} catch (JsonProcessingException e) {

253

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

254

}

255

}

256

257

@PostMapping("/users")

258

public ResponseEntity<Void> createUser(@RequestBody String userJson) {

259

try {

260

LdapUserDetails user = objectMapper.readValue(userJson, LdapUserDetailsImpl.class);

261

// Create user logic here

262

return ResponseEntity.created(URI.create("/api/ldap/users/" + user.getUsername())).build();

263

} catch (JsonProcessingException e) {

264

return ResponseEntity.badRequest().build();

265

}

266

}

267

}

268

```

269

270

### Session Serialization

271

272

```java

273

@Configuration

274

@EnableRedisHttpSession

275

public class SessionConfig {

276

277

@Bean

278

public RedisSerializer<Object> springSessionDefaultRedisSerializer() {

279

return new GenericJackson2JsonRedisSerializer(ldapObjectMapper());

280

}

281

282

private ObjectMapper ldapObjectMapper() {

283

ObjectMapper mapper = new ObjectMapper();

284

mapper.registerModule(new LdapJackson2Module());

285

mapper.activateDefaultTyping(

286

BasicPolymorphicTypeValidator.builder()

287

.allowIfSubType(Object.class)

288

.build(),

289

ObjectMapper.DefaultTyping.NON_FINAL

290

);

291

return mapper;

292

}

293

}

294

```