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

authorities.mddocs/

0

# Authorities Population

1

2

Authority and role mapping from LDAP groups and attributes with customizable population strategies for complex authorization scenarios.

3

4

## Capabilities

5

6

### LdapAuthoritiesPopulator

7

8

Strategy interface for populating user authorities from LDAP directory information.

9

10

```java { .api }

11

/**

12

* Strategy interface for retrieving user authorities from LDAP directory entries

13

*/

14

public interface LdapAuthoritiesPopulator {

15

/**

16

* Retrieves the granted authorities for a user based on their LDAP entry

17

* @param userData the LDAP context operations containing user information

18

* @param username the username of the authenticated user

19

* @return collection of granted authorities for the user

20

*/

21

Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);

22

}

23

```

24

25

### DefaultLdapAuthoritiesPopulator

26

27

Default implementation that populates authorities from LDAP group memberships and user attributes.

28

29

```java { .api }

30

/**

31

* Default LDAP authorities populator that retrieves user authorities from LDAP group memberships

32

* and optionally from user attributes

33

*/

34

public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator, InitializingBean, MessageSourceAware {

35

/**

36

* Creates an authorities populator with context source and group search base

37

* @param contextSource the LDAP context source

38

* @param groupSearchBase the base DN for searching groups (e.g., "ou=groups")

39

*/

40

public DefaultLdapAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase);

41

42

/**

43

* Retrieves granted authorities from LDAP groups and user attributes

44

* @param userData the user's LDAP context operations

45

* @param username the username

46

* @return collection of granted authorities

47

*/

48

public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);

49

50

/**

51

* Sets the LDAP filter for searching groups that contain the user

52

* @param groupSearchFilter filter with {0} placeholder for user DN (default: "member={0}")

53

*/

54

public void setGroupSearchFilter(String groupSearchFilter);

55

56

/**

57

* Sets the attribute name that contains the role/authority name in group entries

58

* @param groupRoleAttribute attribute name (default: "cn")

59

*/

60

public void setGroupRoleAttribute(String groupRoleAttribute);

61

62

/**

63

* Sets the prefix to add to role names extracted from groups

64

* @param rolePrefix prefix to add (default: "ROLE_")

65

*/

66

public void setRolePrefix(String rolePrefix);

67

68

/**

69

* Sets whether to convert role names to uppercase

70

* @param convertToUpperCase true to convert to uppercase (default: true)

71

*/

72

public void setConvertToUpperCase(boolean convertToUpperCase);

73

74

/**

75

* Sets the scope for group searches

76

* @param groupSearchSubtree true to search subtree, false for one level (default: false)

77

*/

78

public void setSearchSubtree(boolean groupSearchSubtree);

79

80

/**

81

* Sets a user attribute that should be used as an additional authority

82

* @param attributeName the name of the user attribute containing role information

83

*/

84

public void setGroupRoleAttribute(String attributeName);

85

86

/**

87

* Sets the default role to assign to all users

88

* @param defaultRole the default role name

89

*/

90

public void setDefaultRole(String defaultRole);

91

92

/**

93

* Sets whether to ignore partial result exceptions during group searches

94

* @param ignore true to ignore partial result exceptions

95

*/

96

public void setIgnorePartialResultException(boolean ignore);

97

}

98

```

99

100

**Usage Examples:**

101

102

```java

103

// Basic authorities populator

104

DefaultLdapAuthoritiesPopulator authoritiesPopulator =

105

new DefaultLdapAuthoritiesPopulator(contextSource, "ou=groups");

106

107

// Customized group search

108

authoritiesPopulator.setGroupSearchFilter("member={0}");

109

authoritiesPopulator.setGroupRoleAttribute("cn");

110

authoritiesPopulator.setRolePrefix("ROLE_");

111

authoritiesPopulator.setConvertToUpperCase(true);

112

113

// Search configuration

114

authoritiesPopulator.setSearchSubtree(true);

115

authoritiesPopulator.setIgnorePartialResultException(true);

116

117

// Default role for all users

118

authoritiesPopulator.setDefaultRole("USER");

119

```

120

121

### UserDetailsServiceLdapAuthoritiesPopulator

122

123

Authorities populator that delegates to a UserDetailsService for authority retrieval.

124

125

```java { .api }

126

/**

127

* LdapAuthoritiesPopulator that obtains authorities from a UserDetailsService

128

*/

129

public class UserDetailsServiceLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {

130

/**

131

* Creates a populator with the specified UserDetailsService

132

* @param userService the UserDetailsService to delegate to

133

*/

134

public UserDetailsServiceLdapAuthoritiesPopulator(UserDetailsService userService);

135

136

/**

137

* Gets authorities by loading UserDetails for the username

138

* @param userData the LDAP context operations (ignored)

139

* @param username the username to look up

140

* @return collection of authorities from UserDetailsService

141

*/

142

public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);

143

}

144

```

145

146

### NestedLdapAuthoritiesPopulator

147

148

Authorities populator that can recursively search nested LDAP groups.

149

150

```java { .api }

151

/**

152

* LDAP authorities populator that can recursively search static nested groups

153

*/

154

public class NestedLdapAuthoritiesPopulator extends DefaultLdapAuthoritiesPopulator {

155

/**

156

* Creates a nested authorities populator

157

* @param contextSource the LDAP context source

158

* @param groupSearchBase the base DN for group searches

159

*/

160

public NestedLdapAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase);

161

162

/**

163

* Sets the maximum search depth for nested groups

164

* @param maxSearchDepth maximum depth (default: 10)

165

*/

166

public void setMaxSearchDepth(int maxSearchDepth);

167

168

/**

169

* Sets additional search filters for nested group searches

170

* @param additionalFilters map of filter names to filter expressions

171

*/

172

public void setAdditionalFilters(Map<String, String> additionalFilters);

173

174

/**

175

* Retrieves authorities including nested group memberships

176

* @param userData the user's LDAP context

177

* @param username the username

178

* @return collection of authorities from direct and nested groups

179

*/

180

public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);

181

}

182

```

183

184

### NullLdapAuthoritiesPopulator

185

186

No-operation authorities populator that returns empty authorities collection.

187

188

```java { .api }

189

/**

190

* Implementation of LdapAuthoritiesPopulator that returns an empty collection of authorities

191

* Useful when authorities are managed outside of LDAP or when no role-based authorization is needed

192

*/

193

public class NullLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {

194

/**

195

* Returns an empty collection of granted authorities

196

* @param userData LDAP context operations for the user (ignored)

197

* @param username the username (ignored)

198

* @return empty collection of authorities

199

*/

200

public Collection<GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username);

201

}

202

```

203

204

## Custom Authority Population Strategies

205

206

### User Attribute-Based Authorities

207

208

```java { .api }

209

/**

210

* Example custom authorities populator that extracts roles from user attributes

211

*/

212

public class UserAttributeAuthoritiesPopulator implements LdapAuthoritiesPopulator {

213

private String roleAttributeName = "employeeType";

214

private String rolePrefix = "ROLE_";

215

216

/**

217

* Sets the user attribute name containing role information

218

* @param roleAttributeName the attribute name

219

*/

220

public void setRoleAttributeName(String roleAttributeName);

221

222

/**

223

* Sets the prefix for role names

224

* @param rolePrefix the role prefix

225

*/

226

public void setRolePrefix(String rolePrefix);

227

228

@Override

229

public Collection<? extends GrantedAuthority> getGrantedAuthorities(

230

DirContextOperations userData, String username) {

231

232

Set<GrantedAuthority> authorities = new HashSet<>();

233

234

// Extract roles from user attributes

235

String[] roles = userData.getStringAttributes(roleAttributeName);

236

if (roles != null) {

237

for (String role : roles) {

238

authorities.add(new SimpleGrantedAuthority(rolePrefix + role.toUpperCase()));

239

}

240

}

241

242

return authorities;

243

}

244

}

245

```

246

247

### Composite Authorities Populator

248

249

```java { .api }

250

/**

251

* Composite authorities populator that combines multiple population strategies

252

*/

253

public class CompositeAuthoritiesPopulator implements LdapAuthoritiesPopulator {

254

private List<LdapAuthoritiesPopulator> populators;

255

256

/**

257

* Creates a composite populator with the specified delegate populators

258

* @param populators list of authorities populators to delegate to

259

*/

260

public CompositeAuthoritiesPopulator(List<LdapAuthoritiesPopulator> populators);

261

262

@Override

263

public Collection<? extends GrantedAuthority> getGrantedAuthorities(

264

DirContextOperations userData, String username) {

265

266

Set<GrantedAuthority> allAuthorities = new HashSet<>();

267

268

// Collect authorities from all populators

269

for (LdapAuthoritiesPopulator populator : populators) {

270

Collection<? extends GrantedAuthority> authorities =

271

populator.getGrantedAuthorities(userData, username);

272

allAuthorities.addAll(authorities);

273

}

274

275

return allAuthorities;

276

}

277

}

278

```

279

280

## Configuration Examples

281

282

### Standard Group-Based Authorization

283

284

```java

285

@Configuration

286

public class LdapAuthoritiesConfig {

287

288

@Bean

289

public DefaultLdapAuthoritiesPopulator authoritiesPopulator() {

290

DefaultLdapAuthoritiesPopulator populator =

291

new DefaultLdapAuthoritiesPopulator(contextSource(), "ou=groups");

292

293

// Configure group search

294

populator.setGroupSearchFilter("member={0}");

295

populator.setGroupRoleAttribute("cn");

296

297

// Role configuration

298

populator.setRolePrefix("ROLE_");

299

populator.setConvertToUpperCase(true);

300

populator.setDefaultRole("USER");

301

302

// Search configuration

303

populator.setSearchSubtree(true);

304

populator.setIgnorePartialResultException(true);

305

306

return populator;

307

}

308

}

309

```

310

311

### Active Directory Group Membership

312

313

```java

314

@Bean

315

public DefaultLdapAuthoritiesPopulator activeDirectoryAuthorities() {

316

DefaultLdapAuthoritiesPopulator populator =

317

new DefaultLdapAuthoritiesPopulator(contextSource(), "");

318

319

// Active Directory uses memberOf attribute

320

populator.setGroupSearchFilter("(&(objectClass=group)(member={0}))");

321

populator.setGroupRoleAttribute("cn");

322

populator.setSearchSubtree(true);

323

324

// Active Directory specific settings

325

populator.setRolePrefix("ROLE_");

326

populator.setConvertToUpperCase(true);

327

328

return populator;

329

}

330

```

331

332

### Multi-Level Group Hierarchy

333

334

```java

335

@Component

336

public class HierarchicalGroupsPopulator implements LdapAuthoritiesPopulator {

337

338

private final SpringSecurityLdapTemplate ldapTemplate;

339

private final String groupSearchBase;

340

341

public HierarchicalGroupsPopulator(SpringSecurityLdapTemplate ldapTemplate) {

342

this.ldapTemplate = ldapTemplate;

343

this.groupSearchBase = "ou=groups";

344

}

345

346

@Override

347

public Collection<? extends GrantedAuthority> getGrantedAuthorities(

348

DirContextOperations userData, String username) {

349

350

Set<GrantedAuthority> authorities = new HashSet<>();

351

Set<String> processedGroups = new HashSet<>();

352

353

// Find direct group memberships

354

Set<String> directGroups = findDirectGroups(userData.getDn().toString());

355

356

// Recursively find parent groups

357

for (String groupDn : directGroups) {

358

collectGroupHierarchy(groupDn, authorities, processedGroups);

359

}

360

361

return authorities;

362

}

363

364

private Set<String> findDirectGroups(String userDn) {

365

return ldapTemplate.searchForSingleAttributeValues(

366

groupSearchBase,

367

"member={0}",

368

new Object[]{userDn},

369

"distinguishedName"

370

);

371

}

372

373

private void collectGroupHierarchy(String groupDn, Set<GrantedAuthority> authorities,

374

Set<String> processedGroups) {

375

376

if (processedGroups.contains(groupDn)) {

377

return; // Avoid circular references

378

}

379

processedGroups.add(groupDn);

380

381

try {

382

// Get group information

383

DirContextOperations group = ldapTemplate.searchForContext("",

384

"distinguishedName={0}", new Object[]{groupDn});

385

386

String roleName = group.getStringAttribute("cn");

387

authorities.add(new SimpleGrantedAuthority("ROLE_" + roleName.toUpperCase()));

388

389

// Find parent groups

390

String[] memberOf = group.getStringAttributes("memberOf");

391

if (memberOf != null) {

392

for (String parentGroupDn : memberOf) {

393

collectGroupHierarchy(parentGroupDn, authorities, processedGroups);

394

}

395

}

396

397

} catch (Exception e) {

398

// Log and continue with other groups

399

logger.warn("Failed to process group: " + groupDn, e);

400

}

401

}

402

}

403

```

404

405

### Role Mapping Configuration

406

407

```java

408

@Component

409

public class MappedRoleAuthoritiesPopulator implements LdapAuthoritiesPopulator {

410

411

private final DefaultLdapAuthoritiesPopulator delegate;

412

private final Map<String, String> roleMapping;

413

414

public MappedRoleAuthoritiesPopulator(ContextSource contextSource) {

415

this.delegate = new DefaultLdapAuthoritiesPopulator(contextSource, "ou=groups");

416

this.roleMapping = initializeRoleMapping();

417

}

418

419

private Map<String, String> initializeRoleMapping() {

420

Map<String, String> mapping = new HashMap<>();

421

mapping.put("LDAP_ADMINS", "ADMIN");

422

mapping.put("LDAP_USERS", "USER");

423

mapping.put("LDAP_MANAGERS", "MANAGER");

424

mapping.put("LDAP_DEVELOPERS", "DEVELOPER");

425

return mapping;

426

}

427

428

@Override

429

public Collection<? extends GrantedAuthority> getGrantedAuthorities(

430

DirContextOperations userData, String username) {

431

432

// Get authorities from delegate

433

Collection<? extends GrantedAuthority> delegateAuthorities =

434

delegate.getGrantedAuthorities(userData, username);

435

436

// Map to application-specific roles

437

Set<GrantedAuthority> mappedAuthorities = new HashSet<>();

438

for (GrantedAuthority authority : delegateAuthorities) {

439

String role = authority.getAuthority().replace("ROLE_", "");

440

String mappedRole = roleMapping.getOrDefault(role, role);

441

mappedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + mappedRole));

442

}

443

444

return mappedAuthorities;

445

}

446

}

447

```

448

449

### Integration with Authentication Provider

450

451

```java

452

@Configuration

453

public class CompleteAuthenticationConfig {

454

455

@Bean

456

public LdapAuthenticationProvider ldapAuthenticationProvider() {

457

// Configure authenticator

458

BindAuthenticator authenticator = new BindAuthenticator(contextSource());

459

authenticator.setUserSearch(userSearch());

460

461

// Configure authorities populator

462

DefaultLdapAuthoritiesPopulator authoritiesPopulator =

463

new DefaultLdapAuthoritiesPopulator(contextSource(), "ou=groups");

464

authoritiesPopulator.setGroupSearchFilter("member={0}");

465

authoritiesPopulator.setGroupRoleAttribute("cn");

466

authoritiesPopulator.setRolePrefix("ROLE_");

467

authoritiesPopulator.setDefaultRole("USER");

468

469

// Create authentication provider

470

LdapAuthenticationProvider provider =

471

new LdapAuthenticationProvider(authenticator, authoritiesPopulator);

472

473

// Custom user details mapping

474

provider.setUserDetailsContextMapper(customUserDetailsMapper());

475

476

return provider;

477

}

478

479

@Bean

480

public UserDetailsContextMapper customUserDetailsMapper() {

481

LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();

482

mapper.setRolePrefix("ROLE_");

483

return mapper;

484

}

485

}

486

```