diff --git a/web/src/main/java/org/springframework/security/web/authentication/preauth/x509/SubjectDnX509PrincipalExtractor.java b/web/src/main/java/org/springframework/security/web/authentication/preauth/x509/SubjectDnX509PrincipalExtractor.java index b690af59c0..442230a963 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/preauth/x509/SubjectDnX509PrincipalExtractor.java +++ b/web/src/main/java/org/springframework/security/web/authentication/preauth/x509/SubjectDnX509PrincipalExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ import org.springframework.util.Assert; * "EMAILADDRESS=jimi@hendrix.org, CN=..." giving a user name "jimi@hendrix.org" * * @author Luke Taylor + * @author Max Batischev */ public class SubjectDnX509PrincipalExtractor implements X509PrincipalExtractor, MessageSourceAware { @@ -52,14 +53,16 @@ public class SubjectDnX509PrincipalExtractor implements X509PrincipalExtractor, private Pattern subjectDnPattern; + private boolean extractPrincipalNameFromX500Principal = false; + public SubjectDnX509PrincipalExtractor() { setSubjectDnRegex("CN=(.*?)(?:,|$)"); } @Override public Object extractPrincipal(X509Certificate clientCert) { - // String subjectDN = clientCert.getSubjectX500Principal().getName(); - String subjectDN = clientCert.getSubjectDN().getName(); + String subjectDN = this.extractPrincipalNameFromX500Principal ? clientCert.getSubjectX500Principal().getName() + : clientCert.getSubjectDN().getName(); this.logger.debug(LogMessage.format("Subject DN is '%s'", subjectDN)); Matcher matcher = this.subjectDnPattern.matcher(subjectDN); if (!matcher.find()) { @@ -98,4 +101,14 @@ public class SubjectDnX509PrincipalExtractor implements X509PrincipalExtractor, this.messages = new MessageSourceAccessor(messageSource); } + /** + * If true then extracts principal name from X500Principal, defaults to {@code false} + * @param extractPrincipalNameFromX500Principal whether to extract the principal name + * from X500Principal + * @since 7.0 + */ + public void setExtractPrincipalNameFromX500Principal(boolean extractPrincipalNameFromX500Principal) { + this.extractPrincipalNameFromX500Principal = extractPrincipalNameFromX500Principal; + } + } diff --git a/web/src/test/java/org/springframework/security/web/authentication/preauth/x509/SubjectDnX509PrincipalExtractorTests.java b/web/src/test/java/org/springframework/security/web/authentication/preauth/x509/SubjectDnX509PrincipalExtractorTests.java index a86b41e0bc..193b83d27c 100644 --- a/web/src/test/java/org/springframework/security/web/authentication/preauth/x509/SubjectDnX509PrincipalExtractorTests.java +++ b/web/src/test/java/org/springframework/security/web/authentication/preauth/x509/SubjectDnX509PrincipalExtractorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,13 @@ public class SubjectDnX509PrincipalExtractorTests { assertThat(principal).isEqualTo("Luke Taylor"); } + @Test + public void defaultCNPatternReturnsPrincipalWhenExtractPrincipalNameFromX500PrincipalIsTrue() throws Exception { + this.extractor.setExtractPrincipalNameFromX500Principal(true); + Object principal = this.extractor.extractPrincipal(X509TestUtils.buildTestCertificate()); + assertThat(principal).isEqualTo("Luke Taylor"); + } + @Test public void matchOnEmailReturnsExpectedPrincipal() throws Exception { this.extractor.setSubjectDnRegex("emailAddress=(.*?),");