From 92f32531edf700e654295dbc785b8e9ecdbc4ba1 Mon Sep 17 00:00:00 2001 From: mpigg Date: Tue, 22 May 2012 12:57:46 -0400 Subject: [PATCH 1/2] SubjectDnRegex that extracts CN from any position in string --- .../preauth/x509/SubjectDnX509PrincipalExtractor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0bb097cd61f..55883c22f09 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 @@ -33,7 +33,7 @@ public class SubjectDnX509PrincipalExtractor implements X509PrincipalExtractor { private Pattern subjectDnPattern; public SubjectDnX509PrincipalExtractor() { - setSubjectDnRegex("CN=(.*?),"); + setSubjectDnRegex("CN=(.*?)(?:,.*)*$"); } public Object extractPrincipal(X509Certificate clientCert) { From 8cc75e193fde815e36881256b9c0a80e38e4e220 Mon Sep 17 00:00:00 2001 From: mpigg Date: Wed, 23 May 2012 07:53:56 -0400 Subject: [PATCH 2/2] Additional unit test for SubjectDnX509PrincipalExtractor --- .../x509/SubjectDnX509PrincipalExtractor.java | 2 +- .../SubjectDnX509PrincipalExtractorTests.java | 6 +++ .../preauth/x509/X509TestUtils.java | 37 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) 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 55883c22f09..77431a379dc 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 @@ -17,7 +17,7 @@ * Obtains the principal from a certificate using a regular expression match against the Subject (as returned by a call * to {@link X509Certificate#getSubjectDN()}). *

- * The regular expression should contain a single group; for example the default expression "CN=(.?)," matches the + * The regular expression should contain a single group; for example the default expression "CN=(.*?)(?:,.*)*$" matches the * common name field. So "CN=Jimi Hendrix, OU=..." will give a user name of "Jimi Hendrix". *

* The matches are case insensitive. So "emailAddress=(.?)," will match "EMAILADDRESS=jimi@hendrix.org, CN=..." giving a 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 efce8776537..2a444885aea 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 @@ -44,4 +44,10 @@ public void matchOnShoeSizeThrowsBadCredentials() throws Exception { extractor.setSubjectDnRegex("shoeSize=(.*?),"); extractor.extractPrincipal(X509TestUtils.buildTestCertificate()); } + + @Test + public void defaultCNPatternReturnsPrincipalAtEndOfDNString() throws Exception { + Object principal = extractor.extractPrincipal(X509TestUtils.buildTestCertificateWithCnAtEnd()); + assertEquals("Duke", principal); + } } diff --git a/web/src/test/java/org/springframework/security/web/authentication/preauth/x509/X509TestUtils.java b/web/src/test/java/org/springframework/security/web/authentication/preauth/x509/X509TestUtils.java index da0af061c4e..18a2472d762 100644 --- a/web/src/test/java/org/springframework/security/web/authentication/preauth/x509/X509TestUtils.java +++ b/web/src/test/java/org/springframework/security/web/authentication/preauth/x509/X509TestUtils.java @@ -98,4 +98,41 @@ public static X509Certificate buildTestCertificate() throws Exception { return (X509Certificate) cf.generateCertificate(in); } + + /** + * Builds an X.509 certificate with a subject DN where the CN field is at the end of the line. + * The actual DN line is: + *

+     *  L=Cupertino,C=US,ST=CA,OU=Java Software,O=Sun Microsystems\, Inc,CN=Duke
+     * 
+ * + */ + public static X509Certificate buildTestCertificateWithCnAtEnd() throws Exception { + String cert = "-----BEGIN CERTIFICATE-----\n" + + "MIIDjTCCAnWgAwIBAgIBATALBgkqhkiG9w0BAQswdTENMAsGA1UEAwwERHVrZTEe\n" + + "MBwGA1UECgwVU3VuIE1pY3Jvc3lzdGVtcywgSW5jMRYwFAYDVQQLDA1KYXZhIFNv\n" + + "ZnR3YXJlMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMxEjAQBgNVBAcMCUN1cGVy\n" + + "dGlubzAeFw0xMjA1MTgxNDQ4MzBaFw0xMzA1MTgxNDQ4MzBaMHUxDTALBgNVBAMM\n" + + "BER1a2UxHjAcBgNVBAoMFVN1biBNaWNyb3N5c3RlbXMsIEluYzEWMBQGA1UECwwN\n" + + "SmF2YSBTb2Z0d2FyZTELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVTMRIwEAYDVQQH\n" + + "DAlDdXBlcnRpbm8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGLaCx\n" + + "Dy5oRJ/FelcoO/lAEApAhR4wxmUIu0guzN0Tx/cuWfyo4349NOxf5XfRcje37B//\n" + + "hyMwK1Q/pRhRYtZlK+O+9tNCAupekmSxEw9wNsRXNJ18QTTvQRPReXhG8gOiGmU2\n" + + "kpTVjpZURo/0WGuEyAWYzH99cQfUM92vIaGKq2fApNfwCULtFnAY9WPDZtwSZYhC\n" + + "qSAoy6B1I2A3i+G5Ep++eCa9PZKCZIPWJiC5+nMmzwCOnQqcZlorsrQ+M+I4GgE2\n" + + "Rryb/AeKoSPsrm4t0aWhFhKcuHpk3jfKhJhi5e+5bnY17pCoY9hx5EK3WqfKL/x1\n" + + "3HKsPpf/MieRWiAdAgMBAAGjKjAoMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8E\n" + + "DDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAdAtXZYCdb7JKzfwY7vEO\n" + + "9TOMyxxwxhxs+26urL2wQWqtRgHXopoi/GGSuZG5aPQcHWLoqZ1f7nZoWfKzJMKw\n" + + "MOvaw6wSSkmEoEvdek3s/bH6Gp0spnykqtb+kunGr/XFxyBhHmfdSroEgzspslFh\n" + + "Glqe/XfrQmFgPWd13GH8mqzSU1zc+0Ka7s68jcuNfz9ble5rT0IrdjRm5E64mVGk\n" + + "aJTAO5N87ks5JjkDHDJzcyYRcIpqBGotJtyZTjGpIeAG8xLGlkSsUg88iUOchI7s\n" + + "dOmse9mpgEjCb4kdZ0PnoxMFjsPR8AoGOz4A5vA19nKqWM8bxK9hqLGKsaiQpQg7\n" + + "bA==\n" + + "-----END CERTIFICATE-----\n"; + ByteArrayInputStream in = new ByteArrayInputStream(cert.getBytes()); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + return (X509Certificate) cf.generateCertificate(in); + } }