1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.spring.security.ldaptive.authentication;
18
19 import java.io.Serial;
20 import java.io.Serializable;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.stream.Collectors;
27 import java.util.stream.Stream;
28 import lombok.AllArgsConstructor;
29 import lombok.Data;
30 import lombok.NoArgsConstructor;
31 import org.bremersee.spring.security.core.authority.mapping.CaseTransformation;
32 import org.ldaptive.SearchScope;
33 import org.springframework.util.ObjectUtils;
34
35
36
37
38
39
40 @Data
41 @NoArgsConstructor
42 public class LdaptiveAuthenticationProperties implements Serializable {
43
44 @Serial
45 private static final long serialVersionUID = 1L;
46
47
48
49
50 protected UsernameToBindDnConverterProperty usernameToBindDnConverter;
51
52
53
54
55 protected String userBaseDn;
56
57
58
59
60 protected List<String> refusedUsernames;
61
62
63
64
65 protected String userObjectClass;
66
67
68
69
70
71 protected String usernameAttribute;
72
73
74
75
76
77 protected String userRdnAttribute;
78
79
80
81
82
83
84
85
86 protected String passwordAttribute;
87
88
89
90
91
92 protected String passwordLastSetAttribute;
93
94
95
96
97
98 protected String userFindOneFilter;
99
100
101
102
103 protected SearchScope userFindOneSearchScope;
104
105
106
107
108 protected String firstNameAttribute;
109
110
111
112
113 protected String lastNameAttribute;
114
115
116
117
118 protected String emailAttribute;
119
120
121
122
123 protected AccountControlEvaluatorProperty accountControlEvaluator;
124
125
126
127
128 protected GroupFetchStrategy groupFetchStrategy;
129
130
131
132
133 protected String memberAttribute;
134
135
136
137
138
139 protected String groupBaseDn;
140
141
142
143
144
145 protected SearchScope groupSearchScope;
146
147
148
149
150
151 protected String groupObjectClass;
152
153
154
155
156
157 protected String groupIdAttribute;
158
159
160
161
162
163 protected String groupMemberAttribute;
164
165
166
167
168
169 protected String groupMemberFormat;
170
171
172
173
174 protected List<RoleMapping> roleMapping;
175
176
177
178
179 protected List<String> defaultRoles;
180
181
182
183
184 protected String rolePrefix;
185
186
187
188
189 protected CaseTransformation roleCaseTransformation;
190
191
192
193
194 protected List<StringReplacement> roleStringReplacements;
195
196
197
198
199
200
201 public Map<String, String> toRoleMappings() {
202 return Stream.ofNullable(getRoleMapping())
203 .flatMap(Collection::stream)
204 .collect(Collectors.toMap(
205 RoleMapping::getSource,
206 RoleMapping::getTarget,
207 (first, second) -> first,
208 LinkedHashMap::new));
209 }
210
211
212
213
214
215
216 public Map<String, String> toRoleStringReplacements() {
217 return Stream.ofNullable(getRoleStringReplacements())
218 .flatMap(Collection::stream)
219 .collect(Collectors.toMap(
220 StringReplacement::getRegex,
221 StringReplacement::getReplacement,
222 (first, second) -> first,
223 LinkedHashMap::new));
224 }
225
226
227
228
229 public static class WithDefaults extends LdaptiveAuthenticationProperties {
230
231 @Serial
232 private static final long serialVersionUID = 1L;
233
234
235
236
237 public WithDefaults() {
238 refusedUsernames = new ArrayList<>();
239
240 usernameToBindDnConverter = UsernameToBindDnConverterProperty.BY_USER_RDN_ATTRIBUTE;
241
242 userObjectClass = "inetOrgPerson";
243 usernameAttribute = "uid";
244
245 userFindOneSearchScope = SearchScope.ONELEVEL;
246 firstNameAttribute = "givenName";
247 lastNameAttribute = "sn";
248 emailAttribute = "mail";
249 memberAttribute = "memberOf";
250 accountControlEvaluator = AccountControlEvaluatorProperty.NONE;
251
252 groupFetchStrategy = GroupFetchStrategy.USER_CONTAINS_GROUPS;
253 groupObjectClass = "groupOfUniqueNames";
254 groupMemberAttribute = "uniqueMember";
255 groupSearchScope = SearchScope.ONELEVEL;
256 roleMapping = new ArrayList<>();
257 defaultRoles = new ArrayList<>();
258 roleStringReplacements = new ArrayList<>();
259 roleCaseTransformation = CaseTransformation.NONE;
260 }
261
262
263
264
265
266
267 @Override
268 public String getUserRdnAttribute() {
269 if (ObjectUtils.isEmpty(userRdnAttribute)) {
270 return usernameAttribute;
271 }
272 return userRdnAttribute;
273 }
274
275
276
277
278
279
280 @Override
281 public String getUserFindOneFilter() {
282 if (ObjectUtils.isEmpty(userFindOneFilter)
283 && !ObjectUtils.isEmpty(getUserObjectClass())
284 && !ObjectUtils.isEmpty(getUsernameAttribute())) {
285 return String
286 .format("(&(objectClass=%s)(%s={0}))", getUserObjectClass(), getUsernameAttribute());
287 }
288 return userFindOneFilter;
289 }
290
291 }
292
293
294
295
296 public enum GroupFetchStrategy {
297
298
299
300
301 NONE,
302
303
304
305
306 USER_CONTAINS_GROUPS,
307
308
309
310
311 GROUP_CONTAINS_USERS
312 }
313
314
315
316
317 @Data
318 @AllArgsConstructor
319 public static class StringReplacement implements Serializable {
320
321 @Serial
322 private static final long serialVersionUID = 1L;
323
324
325
326
327
328 private String regex;
329
330
331
332
333 private String replacement;
334
335
336
337
338 public StringReplacement() {
339 super();
340 }
341 }
342
343
344
345
346 @Data
347 @AllArgsConstructor
348 public static class RoleMapping implements Serializable {
349
350 @Serial
351 private static final long serialVersionUID = 1L;
352
353
354
355
356 private String source;
357
358
359
360
361 private String target;
362
363
364
365
366 public RoleMapping() {
367 super();
368 }
369 }
370
371 }