1
1
/*
2
- * Copyright 2002-2024 the original author or authors.
2
+ * Copyright 2002-2025 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
36
36
import org .springframework .security .web .authentication .preauth .x509 .X509AuthenticationFilter ;
37
37
import org .springframework .security .web .authentication .preauth .x509 .X509PrincipalExtractor ;
38
38
import org .springframework .security .web .context .RequestAttributeSecurityContextRepository ;
39
+ import org .springframework .util .Assert ;
40
+ import org .springframework .util .StringUtils ;
39
41
40
42
/**
41
43
* Adds X509 based pre authentication to an application. Since validating the certificate
74
76
*
75
77
* @author Rob Winch
76
78
* @author Ngoc Nhan
79
+ * @author Max Batischev
77
80
* @since 3.2
78
81
*/
79
82
public final class X509Configurer <H extends HttpSecurityBuilder <H >>
@@ -87,6 +90,8 @@ public final class X509Configurer<H extends HttpSecurityBuilder<H>>
87
90
88
91
private AuthenticationDetailsSource <HttpServletRequest , PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails > authenticationDetailsSource ;
89
92
93
+ private String subjectPrincipalRegex ;
94
+
90
95
/**
91
96
* Creates a new instance
92
97
*
@@ -163,9 +168,8 @@ public X509Configurer<H> authenticationUserDetailsService(
163
168
* @return the {@link X509Configurer} for further customizations
164
169
*/
165
170
public X509Configurer <H > subjectPrincipalRegex (String subjectPrincipalRegex ) {
166
- SubjectDnX509PrincipalExtractor principalExtractor = new SubjectDnX509PrincipalExtractor ();
167
- principalExtractor .setSubjectDnRegex (subjectPrincipalRegex );
168
- this .x509PrincipalExtractor = principalExtractor ;
171
+ Assert .hasText (subjectPrincipalRegex , "subjectPrincipalRegex cannot be null or empty" );
172
+ this .subjectPrincipalRegex = subjectPrincipalRegex ;
169
173
return this ;
170
174
}
171
175
@@ -187,9 +191,7 @@ private X509AuthenticationFilter getFilter(AuthenticationManager authenticationM
187
191
if (this .x509AuthenticationFilter == null ) {
188
192
this .x509AuthenticationFilter = new X509AuthenticationFilter ();
189
193
this .x509AuthenticationFilter .setAuthenticationManager (authenticationManager );
190
- if (this .x509PrincipalExtractor != null ) {
191
- this .x509AuthenticationFilter .setPrincipalExtractor (this .x509PrincipalExtractor );
192
- }
194
+ this .x509AuthenticationFilter .setPrincipalExtractor (getX509PrincipalExtractor (http ));
193
195
if (this .authenticationDetailsSource != null ) {
194
196
this .x509AuthenticationFilter .setAuthenticationDetailsSource (this .authenticationDetailsSource );
195
197
}
@@ -209,6 +211,22 @@ private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> ge
209
211
return this .authenticationUserDetailsService ;
210
212
}
211
213
214
+ private X509PrincipalExtractor getX509PrincipalExtractor (H http ) {
215
+ if (this .x509PrincipalExtractor != null ) {
216
+ return this .x509PrincipalExtractor ;
217
+ }
218
+ X509PrincipalExtractor extractor = getSharedOrBean (http , X509PrincipalExtractor .class );
219
+ if (extractor != null ) {
220
+ return extractor ;
221
+ }
222
+ SubjectDnX509PrincipalExtractor principalExtractor = new SubjectDnX509PrincipalExtractor ();
223
+ if (StringUtils .hasText (this .subjectPrincipalRegex )) {
224
+ principalExtractor .setSubjectDnRegex (this .subjectPrincipalRegex );
225
+ }
226
+ this .x509PrincipalExtractor = principalExtractor ;
227
+ return this .x509PrincipalExtractor ;
228
+ }
229
+
212
230
private <C > C getSharedOrBean (H http , Class <C > type ) {
213
231
C shared = http .getSharedObject (type );
214
232
if (shared != null ) {
0 commit comments