From 647a6dc798f3674e6072e88ad158d41534cba232 Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Sun, 19 Apr 2020 18:54:43 +0200 Subject: [PATCH] JAVA-1130: Update the x509 mutual authentication codebase --- .../spring-security-x509/keystore/Makefile | 92 ------------------ .../keystore/keystore.jks | Bin 9310 -> 0 bytes .../src/main/resources/application.properties | 2 +- .../x509/X509AuthenticationServer.java | 8 +- .../src/main/resources/application.properties | 4 +- .../src/main/resources/keystore.jks | Bin 9310 -> 0 bytes .../spring-security-x509/store/clientBob.p12 | Bin 0 -> 4024 bytes .../spring-security-x509/store/keystore.jks | Bin 0 -> 3718 bytes .../spring-security-x509/store/rootCA.crt | 30 ++++++ .../spring-security-x509/store/truststore.jks | Bin 0 -> 1358 bytes 10 files changed, 39 insertions(+), 97 deletions(-) delete mode 100644 spring-security-modules/spring-security-x509/keystore/Makefile delete mode 100644 spring-security-modules/spring-security-x509/keystore/keystore.jks delete mode 100644 spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/resources/keystore.jks create mode 100644 spring-security-modules/spring-security-x509/store/clientBob.p12 create mode 100644 spring-security-modules/spring-security-x509/store/keystore.jks create mode 100644 spring-security-modules/spring-security-x509/store/rootCA.crt create mode 100644 spring-security-modules/spring-security-x509/store/truststore.jks diff --git a/spring-security-modules/spring-security-x509/keystore/Makefile b/spring-security-modules/spring-security-x509/keystore/Makefile deleted file mode 100644 index 2cd7c55c5b..0000000000 --- a/spring-security-modules/spring-security-x509/keystore/Makefile +++ /dev/null @@ -1,92 +0,0 @@ -PASSWORD=changeit -KEYSTORE=keystore.jks -HOSTNAME=localhost -CLIENTNAME=cid -CLIENT_PRIVATE_KEY="${CLIENTNAME}_pk" - -# CN = Common Name -# OU = Organization Unit -# O = Organization Name -# L = Locality Name -# ST = State Name -# C = Country (2-letter Country Code) -# E = Email -DNAME_CA='CN=Baeldung CA,OU=baeldung.com,O=Baeldung,L=SomeCity,ST=SomeState,C=CC' -# For server certificates, the Common Name (CN) must be the hostname -DNAME_HOST='CN=$(HOSTNAME),OU=baeldung.com,O=Baeldung,L=SomeCity,ST=SomeState,C=CC' -DNAME_CLIENT='CN=$(CLIENTNAME),OU=baeldung.com,O=Baeldung,L=SomeCity,ST=SomeState,C=CC' -TRUSTSTORE=truststore.jks - -all: clean create-keystore add-host create-truststore add-client - -create-keystore: - # Generate a certificate authority (CA) - keytool -genkey -alias ca -ext san=dns:localhost,ip:127.0.0.1 -ext BC=ca:true \ - -keyalg RSA -keysize 4096 -sigalg SHA512withRSA -keypass $(PASSWORD) \ - -validity 3650 -dname $(DNAME_CA) \ - -keystore $(KEYSTORE) -storepass $(PASSWORD) - -add-host: - # Generate a host certificate - keytool -genkey -alias $(HOSTNAME) -ext san=dns:localhost,ip:127.0.0.1 \ - -keyalg RSA -keysize 4096 -sigalg SHA512withRSA -keypass $(PASSWORD) \ - -validity 3650 -dname $(DNAME_HOST) \ - -keystore $(KEYSTORE) -storepass $(PASSWORD) - # Generate a host certificate signing request - keytool -certreq -alias $(HOSTNAME) -ext san=dns:localhost,ip:127.0.0.1 -ext BC=ca:true \ - -keyalg RSA -keysize 4096 -sigalg SHA512withRSA \ - -validity 3650 -file "$(HOSTNAME).csr" \ - -keystore $(KEYSTORE) -storepass $(PASSWORD) - # Generate signed certificate with the certificate authority - keytool -gencert -alias ca -ext san=dns:localhost,ip:127.0.0.1 \ - -validity 3650 -sigalg SHA512withRSA \ - -infile "$(HOSTNAME).csr" -outfile "$(HOSTNAME).crt" -rfc \ - -keystore $(KEYSTORE) -storepass $(PASSWORD) - # Import signed certificate into the keystore - keytool -import -trustcacerts -alias $(HOSTNAME) -ext san=dns:localhost,ip:127.0.0.1 \ - -file "$(HOSTNAME).crt" \ - -keystore $(KEYSTORE) -storepass $(PASSWORD) - -export-authority: - # Export certificate authority - keytool -export -alias ca -ext san=dns:localhost,ip:127.0.0.1 -file ca.crt -rfc \ - -keystore $(KEYSTORE) -storepass $(PASSWORD) - - -create-truststore: export-authority - # Import certificate authority into a new truststore - keytool -import -trustcacerts -noprompt -alias ca -ext san=dns:localhost,ip:127.0.0.1 -file ca.crt \ - -keystore $(TRUSTSTORE) -storepass $(PASSWORD) - -add-client: - # Generate client certificate - keytool -genkey -alias $(CLIENT_PRIVATE_KEY) -ext san=dns:localhost,ip:127.0.0.1 \ - -keyalg RSA -keysize 4096 -sigalg SHA512withRSA -keypass $(PASSWORD) \ - -validity 3650 -dname $(DNAME_CLIENT) \ - -keystore $(TRUSTSTORE) -storepass $(PASSWORD) - # Generate a host certificate signing request - keytool -certreq -alias $(CLIENT_PRIVATE_KEY) -ext san=dns:localhost,ip:127.0.0.1 -ext BC=ca:true \ - -keyalg RSA -keysize 4096 -sigalg SHA512withRSA \ - -validity 3650 -file "$(CLIENTNAME).csr" \ - -keystore $(TRUSTSTORE) -storepass $(PASSWORD) - # Generate signed certificate with the certificate authority - keytool -gencert -alias ca -ext san=dns:localhost,ip:127.0.0.1 \ - -validity 3650 -sigalg SHA512withRSA \ - -infile "$(CLIENTNAME).csr" -outfile "$(CLIENTNAME).crt" -rfc \ - -keystore $(KEYSTORE) -storepass $(PASSWORD) - # Import signed certificate into the truststore - keytool -import -trustcacerts -alias $(CLIENTNAME) -ext san=dns:localhost,ip:127.0.0.1 \ - -file "$(CLIENTNAME).crt" \ - -keystore $(TRUSTSTORE) -storepass $(PASSWORD) - # Export private certificate for importing into a browser - keytool -importkeystore -srcalias $(CLIENT_PRIVATE_KEY) -ext san=dns:localhost,ip:127.0.0.1 \ - -srckeystore $(TRUSTSTORE) -srcstorepass $(PASSWORD) \ - -destkeystore "$(CLIENTNAME).p12" -deststorepass $(PASSWORD) \ - -deststoretype PKCS12 - # Delete client private key as truststore should not contain any private keys - keytool -delete -alias $(CLIENT_PRIVATE_KEY) \ - -keystore $(TRUSTSTORE) -storepass $(PASSWORD) - -clean: - # Remove generated artifacts - find . \( -name "$(CLIENTNAME)*" -o -name "$(HOSTNAME)*" -o -name "$(KEYSTORE)" -o -name "$(TRUSTSTORE)" -o -name ca.crt \) -type f -exec rm -f {} \; diff --git a/spring-security-modules/spring-security-x509/keystore/keystore.jks b/spring-security-modules/spring-security-x509/keystore/keystore.jks deleted file mode 100644 index 044a820c39524f1ef3c470105dbaa82b63af0493..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9310 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 DeRHq; diff --git a/spring-security-modules/spring-security-x509/spring-security-x509-basic-auth/src/main/resources/application.properties b/spring-security-modules/spring-security-x509/spring-security-x509-basic-auth/src/main/resources/application.properties index 53dfe9976a..208cc90b47 100644 --- a/spring-security-modules/spring-security-x509/spring-security-x509-basic-auth/src/main/resources/application.properties +++ b/spring-security-modules/spring-security-x509/spring-security-x509-basic-auth/src/main/resources/application.properties @@ -1,4 +1,4 @@ -server.ssl.key-store=keystore/keystore.jks +server.ssl.key-store=store/keystore.jks server.ssl.key-store-password=changeit server.ssl.key-alias=localhost server.ssl.key-password=changeit diff --git a/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/java/com/baeldung/spring/security/x509/X509AuthenticationServer.java b/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/java/com/baeldung/spring/security/x509/X509AuthenticationServer.java index 050423238e..18bbfba835 100644 --- a/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/java/com/baeldung/spring/security/x509/X509AuthenticationServer.java +++ b/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/java/com/baeldung/spring/security/x509/X509AuthenticationServer.java @@ -23,7 +23,11 @@ public class X509AuthenticationServer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().authenticated().and().x509().subjectPrincipalRegex("CN=(.*?)(?:,|$)").userDetailsService(userDetailsService()); + http.authorizeRequests().anyRequest().authenticated() + .and() + .x509() + .subjectPrincipalRegex("CN=(.*?)(?:,|$)") + .userDetailsService(userDetailsService()); } @Bean @@ -31,7 +35,7 @@ public class X509AuthenticationServer extends WebSecurityConfigurerAdapter { return new UserDetailsService() { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - if (username.equals("cid")) { + if (username.equals("Bob")) { return new User(username, "", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); } throw new UsernameNotFoundException("User not found!"); diff --git a/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/resources/application.properties b/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/resources/application.properties index 743c9c4582..b841a37916 100644 --- a/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/resources/application.properties +++ b/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/resources/application.properties @@ -1,4 +1,4 @@ -server.ssl.key-store=../keystore/keystore.jks +server.ssl.key-store=store/keystore.jks server.ssl.key-store-password=changeit server.ssl.key-alias=localhost server.ssl.key-password=changeit @@ -6,6 +6,6 @@ server.ssl.enabled=true server.port=8443 spring.security.user.name=Admin spring.security.user.password=admin -server.ssl.trust-store=../keystore/truststore.jks +server.ssl.trust-store=store/truststore.jks server.ssl.trust-store-password=changeit server.ssl.client-auth=need \ No newline at end of file diff --git a/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/resources/keystore.jks b/spring-security-modules/spring-security-x509/spring-security-x509-client-auth/src/main/resources/keystore.jks deleted file mode 100644 index 044a820c39524f1ef3c470105dbaa82b63af0493..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9310 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 DeRHq; diff --git a/spring-security-modules/spring-security-x509/store/clientBob.p12 b/spring-security-modules/spring-security-x509/store/clientBob.p12 new file mode 100644 index 0000000000000000000000000000000000000000..e5d6dbcefbfaffa2502b1ed9613bc1cb2f9ce573 GIT binary patch literal 4024 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 SChlA@P5Y@C!_vP&?!N$UlZxN~ literal 0 HcmV?d00001 diff --git a/spring-security-modules/spring-security-x509/store/keystore.jks b/spring-security-modules/spring-security-x509/store/keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..8650651a1e0a884555a4219049340ce2314315cb GIT binary patch literal 3718 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 kxy)FR?K>|cBR4C9fw-ZlfiN3$C<`+Wk5gi5 zPD*KBx?XaAu7R95uaSX)iJ_&TnW34HMU*(NF^Fpp<>J=Z#H5652_q{5a}yIk1JGSu zOifIT49BM$^W7KtHD8{=CFWDwpFN*~jdU}7-`?18;<3|VO_vGD;VNb<+qW>AuXi$d z+oJIE)#-n`7izGno#5qty|q-+Pj^c!t5xPwt8FLS9Hi=PSA_?At#G$8^7(OTna9h| zU(*}v$}+D{xY!uv$o}!{!5pDUs)di5K5kjHEJR_(dAEf^p9QM-s5QNnDbY_8xtY14 ze!I&QbG^RL{d}_;m7|jnojABZ_RRSUl0hOS|L+8GPPIH${aC)WCOYZOTt~J`+Zx`v ztz#^&C$$!4y6MDMqL)gMoDi10a{ZzWX*Q8hF{?3UT-ajz-#M3b0%0(^X%jQz9 z(*yYS1gA(^+|%v*vt@(bb5C#m zqr1t9XZfFGFE&lnR$O%ml^CD z{o;x)T|blmM)~@se4iVSxWE5ot?8ft;N1Ti&QlKZ*s0xjVYUz0WGb8PGuz)oclE_t z3I!RT`y}!exvDpQUOri8a{s@3i;6{Rnm(@Ceb17c?{Bijs=xeyWd9n^_u8{|(slmd z`c=PJWtWE(8cY9e{TReJS2gx-OMJZeOF<@PMh3>k!3Kc_vcPmF%f}+dBJxQvl(Soo z=TPMDBWBa5xaB_Hp0vY29we>IB4HrbfL#GUNP#dT<9`-b17;wFoa}&U8<^}E8Pay; zebn#TwpV0c<<~9w^A_inu9@Bce!`dTz>_cDuzh;BWJe-bVHkJR^}E^gmn&{;WLWoL z=YyY9->QqOczDVCG3(*_sdj%nxGxn4#EB?QJhkkWuNxZ!|D1)ozi%GBU%N~2gvZ;M zYSlOf>+?yq*YDh&_v*{xX~Nw~>-svkta}=n{{GD#;jiq@(O);bXJxQh?wJ(Icy6(T zJR{?r4qs#K)+&R~#fi%%&gkfg+L^P8S8TSjj3&Q)!(BcRu5z}ms?ullcl}Xv&C)N< z@S3}Rf~>WXOOo6b?x(W*5A{kO-**E-gD3D1RFrm1-CeZKbAvKgL{4}&FC*7<$6{b(+^U$i;;V4Pmt zv=YHOzmC{4^Q{*|w<&tR_Lz90PnLUW66Z^n8$VZW(21SmsiDp~hdeXV-epP%lLX{{Pt~YuAkgeTRL%j-Pav1UuxNS z9G07G_!P#)_@z?sMs=5H(tpdsH0#^(y3D_O{F^7Y9jblszw$@S4hKVfYpsuWzDC@Z zySMI8(u4W>yZHG%nwAAWDG8X{u^;1It literal 0 HcmV?d00001