From 62d9eed9fd95910b17bcf7c3e35b48c0093ebf8a Mon Sep 17 00:00:00 2001 From: Holger Steinhauer Date: Wed, 7 Feb 2018 12:45:24 +0000 Subject: [PATCH 1/6] BAEL-1489: Introducing Red13PasswordEncoder Something to nether use, but explain the idea of delegation and prefixing. --- .../passwordstorage/Rot13PasswordEncoder.java | 30 ++++++++++++++++ .../Rot13PasswordEncoderTest.java | 36 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java create mode 100644 spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java new file mode 100644 index 0000000000..85cf987e1d --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java @@ -0,0 +1,30 @@ +package com.baeldung.passwordstorage; + +import org.springframework.security.crypto.password.PasswordEncoder; + +/** + * DISCLAIMER: Never ever use this in any production environment! + *

+ * Does only work for characters. + */ +public class Rot13PasswordEncoder implements PasswordEncoder { + + @Override + public String encode(CharSequence rawPassword) { + StringBuffer result = new StringBuffer(rawPassword.length()); + rawPassword.chars().forEach(charCode -> { + if (charCode >= 65 && charCode <= 77 || charCode >= 97 && charCode <= 109) { + result.append(Character.toChars(charCode + 13)); + } else if (charCode >= 78 && charCode <= 90 || charCode >= 110 && charCode <= 133) { + result.append(Character.toChars(charCode - 13)); + } + }); + + return result.toString(); + } + + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + return encode(rawPassword).equals(encodedPassword); + } +} diff --git a/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java b/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java new file mode 100644 index 0000000000..08221e0185 --- /dev/null +++ b/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java @@ -0,0 +1,36 @@ +package com.baeldung.passwordstorage; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class Rot13PasswordEncoderTest { + + private final Rot13PasswordEncoder encoder = new Rot13PasswordEncoder(); + + @Test + public void given_theEncodedPassword_should_returnTheClearTextPassword() { + String password = "baeldung"; + String encoded = encoder.encode(password); + String actualResult = encoder.encode(encoded); + + assertThat(actualResult, is(password)); + } + + @Test + public void given_correctPassword_should_returnTrue() { + String password = "baeldung"; + String encoded = encoder.encode(password); + boolean actualResult = encoder.matches(password, encoded); + + assertThat(actualResult, is(true)); + } + + @Test + public void given_incorrectPassword_should_returnFalse() { + boolean actualResult = encoder.matches("baeldung", "spring"); + + assertThat(actualResult, is(false)); + } +} \ No newline at end of file From e61b157057768d60661e6dcee1eec1587895be60 Mon Sep 17 00:00:00 2001 From: Holger Steinhauer Date: Wed, 7 Feb 2018 21:13:00 +0000 Subject: [PATCH 2/6] BAEL-1489: Applying Baeldung code styles and cleaning up --- .../BaeldungPasswordEncoderSetup.java | 33 +++++++++++++++ .../passwordstorage/Rot13PasswordEncoder.java | 34 ++++++++-------- .../Rot13PasswordEncoderTest.java | 40 +++++++++---------- 3 files changed, 71 insertions(+), 36 deletions(-) create mode 100644 spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java new file mode 100644 index 0000000000..89eeb0f826 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java @@ -0,0 +1,33 @@ +package com.baeldung.passwordstorage; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.DelegatingPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class BaeldungPasswordEncoderSetup { + + @Bean + public PasswordEncoder passwordEncoder() { + // set up the list of supported encoders and their prefixes + String encodingId = "rot13"; + Map encoders = new HashMap<>(); + encoders.put(encodingId, new Rot13PasswordEncoder()); + encoders.put("scrypt", new SCryptPasswordEncoder()); + encoders.put("bcrypt", new BCryptPasswordEncoder()); + + // get an instance of the DelegatingPasswordEncoder, set up to use our instance as default encoder + DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(encodingId, encoders); + + // configure our instance as default encoder for actual matching + delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(encoders.get(encodingId)); + + return delegatingPasswordEncoder; + } +} diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java index 85cf987e1d..52de412de7 100644 --- a/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java +++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java @@ -9,22 +9,24 @@ import org.springframework.security.crypto.password.PasswordEncoder; */ public class Rot13PasswordEncoder implements PasswordEncoder { - @Override - public String encode(CharSequence rawPassword) { - StringBuffer result = new StringBuffer(rawPassword.length()); - rawPassword.chars().forEach(charCode -> { - if (charCode >= 65 && charCode <= 77 || charCode >= 97 && charCode <= 109) { - result.append(Character.toChars(charCode + 13)); - } else if (charCode >= 78 && charCode <= 90 || charCode >= 110 && charCode <= 133) { - result.append(Character.toChars(charCode - 13)); - } - }); + @Override + public String encode(CharSequence rawPassword) { + StringBuffer result = new StringBuffer(rawPassword.length()); + rawPassword + .chars() + .forEach(charCode -> { + if (charCode >= 65 && charCode <= 77 || charCode >= 97 && charCode <= 109) { + result.append(Character.toChars(charCode + 13)); + } else if (charCode >= 78 && charCode <= 90 || charCode >= 110 && charCode <= 133) { + result.append(Character.toChars(charCode - 13)); + } + }); - return result.toString(); - } + return result.toString(); + } - @Override - public boolean matches(CharSequence rawPassword, String encodedPassword) { - return encode(rawPassword).equals(encodedPassword); - } + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + return encode(rawPassword).equals(encodedPassword); + } } diff --git a/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java b/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java index 08221e0185..fce83a33df 100644 --- a/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java +++ b/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java @@ -7,30 +7,30 @@ import static org.junit.Assert.assertThat; public class Rot13PasswordEncoderTest { - private final Rot13PasswordEncoder encoder = new Rot13PasswordEncoder(); + private final Rot13PasswordEncoder encoder = new Rot13PasswordEncoder(); - @Test - public void given_theEncodedPassword_should_returnTheClearTextPassword() { - String password = "baeldung"; - String encoded = encoder.encode(password); - String actualResult = encoder.encode(encoded); + @Test + public void given_theEncodedPassword_should_returnTheClearTextPassword() { + String password = "baeldung"; + String encoded = encoder.encode(password); + String actualResult = encoder.encode(encoded); - assertThat(actualResult, is(password)); - } + assertThat(actualResult, is(password)); + } - @Test - public void given_correctPassword_should_returnTrue() { - String password = "baeldung"; - String encoded = encoder.encode(password); - boolean actualResult = encoder.matches(password, encoded); + @Test + public void given_correctPassword_should_returnTrue() { + String password = "baeldung"; + String encoded = encoder.encode(password); + boolean actualResult = encoder.matches(password, encoded); - assertThat(actualResult, is(true)); - } + assertThat(actualResult, is(true)); + } - @Test - public void given_incorrectPassword_should_returnFalse() { - boolean actualResult = encoder.matches("baeldung", "spring"); + @Test + public void given_incorrectPassword_should_returnFalse() { + boolean actualResult = encoder.matches("baeldung", "spring"); - assertThat(actualResult, is(false)); - } + assertThat(actualResult, is(false)); + } } \ No newline at end of file From 99ef66b2cbc7aeb753d83074a9ab0a6d554c454d Mon Sep 17 00:00:00 2001 From: Holger Steinhauer Date: Wed, 7 Feb 2018 21:21:48 +0000 Subject: [PATCH 3/6] BAEL-1489: Naming test methods correctly --- .../baeldung/passwordstorage/Rot13PasswordEncoderTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java b/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java index fce83a33df..b515d47fbc 100644 --- a/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java +++ b/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java @@ -10,7 +10,7 @@ public class Rot13PasswordEncoderTest { private final Rot13PasswordEncoder encoder = new Rot13PasswordEncoder(); @Test - public void given_theEncodedPassword_should_returnTheClearTextPassword() { + public void givenEncodedPassword_whenEncodeIsCalledWithTheEncodedPassword_thenTheClearTextPassword() { String password = "baeldung"; String encoded = encoder.encode(password); String actualResult = encoder.encode(encoded); @@ -19,7 +19,7 @@ public class Rot13PasswordEncoderTest { } @Test - public void given_correctPassword_should_returnTrue() { + public void givenCorrectPassword_whenMatchesIsCalled_thenReturnTrue() { String password = "baeldung"; String encoded = encoder.encode(password); boolean actualResult = encoder.matches(password, encoded); @@ -28,7 +28,7 @@ public class Rot13PasswordEncoderTest { } @Test - public void given_incorrectPassword_should_returnFalse() { + public void givenIncorrectPassword_whenMatchesIsCalled_thenReturnFalse() { boolean actualResult = encoder.matches("baeldung", "spring"); assertThat(actualResult, is(false)); From 20ef3b0299bc085cc98eabcb3cca05c1dd405422 Mon Sep 17 00:00:00 2001 From: Holger Steinhauer Date: Sun, 18 Feb 2018 21:44:54 +0000 Subject: [PATCH 4/6] BAEL-1489: Refactoring and successful login event handling --- .../BaeldungPasswordEncoderSetup.java | 44 ++++++++------ .../PasswordStorageApplication.java | 13 +++++ .../PasswordStorageWebSecurityConfigurer.java | 57 +++++++++++++++++++ .../passwordstorage/Rot13PasswordEncoder.java | 32 ----------- .../Rot13PasswordEncoderTest.java | 36 ------------ 5 files changed, 96 insertions(+), 86 deletions(-) create mode 100644 spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageApplication.java create mode 100644 spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java delete mode 100644 spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java delete mode 100644 spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java index 89eeb0f826..94edf85631 100644 --- a/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java +++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java @@ -1,33 +1,41 @@ package com.baeldung.passwordstorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.DelegatingPasswordEncoder; +import org.springframework.security.authentication.AuthenticationEventPublisher; +import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.event.AuthenticationSuccessEvent; +import org.springframework.security.core.Authentication; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; - -import java.util.HashMap; -import java.util.Map; @Configuration public class BaeldungPasswordEncoderSetup { + private final static Logger LOG = LoggerFactory.getLogger(BaeldungPasswordEncoderSetup.class); + @Bean - public PasswordEncoder passwordEncoder() { - // set up the list of supported encoders and their prefixes - String encodingId = "rot13"; - Map encoders = new HashMap<>(); - encoders.put(encodingId, new Rot13PasswordEncoder()); - encoders.put("scrypt", new SCryptPasswordEncoder()); - encoders.put("bcrypt", new BCryptPasswordEncoder()); + public AuthenticationEventPublisher authenticationEventPublisher(final ApplicationEventPublisher publisher) { + return new DefaultAuthenticationEventPublisher(publisher); + } - // get an instance of the DelegatingPasswordEncoder, set up to use our instance as default encoder - DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(encodingId, encoders); + @Bean + public ApplicationListener authenticationSuccessListener(final PasswordEncoder encoder) { + return (AuthenticationSuccessEvent event) -> { + final Authentication authentication = event.getAuthentication(); - // configure our instance as default encoder for actual matching - delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(encoders.get(encodingId)); + if (authentication instanceof UsernamePasswordAuthenticationToken && authentication.getCredentials() != null) { + final CharSequence clearTextPassword = (CharSequence) authentication.getCredentials(); // 1 + final String newPasswordHash = encoder.encode(clearTextPassword); // 2 - return delegatingPasswordEncoder; + LOG.info("New password hash {} for user {}", newPasswordHash, authentication.getName()); + + ((UsernamePasswordAuthenticationToken) authentication).eraseCredentials(); // 3 + } + }; } } diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageApplication.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageApplication.java new file mode 100644 index 0000000000..173d979a45 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.passwordstorage; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PasswordStorageApplication { + + public static void main(String[] args) { + SpringApplication.run(PasswordStorageApplication.class, args); + } + +} diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java new file mode 100644 index 0000000000..c73461daaa --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java @@ -0,0 +1,57 @@ +package com.baeldung.passwordstorage; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationEventPublisher; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.DelegatingPasswordEncoder; +import org.springframework.security.crypto.password.MessageDigestPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class PasswordStorageWebSecurityConfigurer extends WebSecurityConfigurerAdapter { + + private final AuthenticationEventPublisher eventPublisher; + private final UserDetailsService userDetailsService; + + @Autowired + public PasswordStorageWebSecurityConfigurer(AuthenticationEventPublisher eventPublisher, UserDetailsService userDetailsService) { + this.eventPublisher = eventPublisher; + this.userDetailsService = userDetailsService; + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.eraseCredentials(false) // 4 + .authenticationEventPublisher(eventPublisher) + .userDetailsService(userDetailsService) + .passwordEncoder(passwordEncoder()); + } + + @Bean + public PasswordEncoder passwordEncoder() { + // set up the list of supported encoders and their prefixes + String encodingId = "bcrypt"; + Map encoders = new HashMap<>(); + encoders.put(encodingId, new BCryptPasswordEncoder()); + encoders.put("scrypt", new SCryptPasswordEncoder()); + encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256")); + + // get an instance of the DelegatingPasswordEncoder, set up to use our instance as default encoder + DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(encodingId, encoders); + + // configure our instance as default encoder for actual matching + delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(encoders.get(encodingId)); + + return delegatingPasswordEncoder; + } + +} diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java deleted file mode 100644 index 52de412de7..0000000000 --- a/spring-5-security/src/main/java/com/baeldung/passwordstorage/Rot13PasswordEncoder.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.baeldung.passwordstorage; - -import org.springframework.security.crypto.password.PasswordEncoder; - -/** - * DISCLAIMER: Never ever use this in any production environment! - *

- * Does only work for characters. - */ -public class Rot13PasswordEncoder implements PasswordEncoder { - - @Override - public String encode(CharSequence rawPassword) { - StringBuffer result = new StringBuffer(rawPassword.length()); - rawPassword - .chars() - .forEach(charCode -> { - if (charCode >= 65 && charCode <= 77 || charCode >= 97 && charCode <= 109) { - result.append(Character.toChars(charCode + 13)); - } else if (charCode >= 78 && charCode <= 90 || charCode >= 110 && charCode <= 133) { - result.append(Character.toChars(charCode - 13)); - } - }); - - return result.toString(); - } - - @Override - public boolean matches(CharSequence rawPassword, String encodedPassword) { - return encode(rawPassword).equals(encodedPassword); - } -} diff --git a/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java b/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java deleted file mode 100644 index b515d47fbc..0000000000 --- a/spring-5-security/src/test/java/com/baeldung/passwordstorage/Rot13PasswordEncoderTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.baeldung.passwordstorage; - -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -public class Rot13PasswordEncoderTest { - - private final Rot13PasswordEncoder encoder = new Rot13PasswordEncoder(); - - @Test - public void givenEncodedPassword_whenEncodeIsCalledWithTheEncodedPassword_thenTheClearTextPassword() { - String password = "baeldung"; - String encoded = encoder.encode(password); - String actualResult = encoder.encode(encoded); - - assertThat(actualResult, is(password)); - } - - @Test - public void givenCorrectPassword_whenMatchesIsCalled_thenReturnTrue() { - String password = "baeldung"; - String encoded = encoder.encode(password); - boolean actualResult = encoder.matches(password, encoded); - - assertThat(actualResult, is(true)); - } - - @Test - public void givenIncorrectPassword_whenMatchesIsCalled_thenReturnFalse() { - boolean actualResult = encoder.matches("baeldung", "spring"); - - assertThat(actualResult, is(false)); - } -} \ No newline at end of file From 75b3301cc345e3370492b36263709d16c1667832 Mon Sep 17 00:00:00 2001 From: Holger Steinhauer Date: Sun, 18 Feb 2018 21:46:21 +0000 Subject: [PATCH 5/6] BAEL-1489: Clean up --- .../passwordstorage/PasswordStorageWebSecurityConfigurer.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java index c73461daaa..0773de4bd6 100644 --- a/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java +++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java @@ -45,10 +45,7 @@ public class PasswordStorageWebSecurityConfigurer extends WebSecurityConfigurerA encoders.put("scrypt", new SCryptPasswordEncoder()); encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256")); - // get an instance of the DelegatingPasswordEncoder, set up to use our instance as default encoder DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(encodingId, encoders); - - // configure our instance as default encoder for actual matching delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(encoders.get(encodingId)); return delegatingPasswordEncoder; From 73f248ffddfb7e101e99a1e1b27d182c894fe52b Mon Sep 17 00:00:00 2001 From: Holger Steinhauer Date: Sun, 25 Feb 2018 10:39:01 +0000 Subject: [PATCH 6/6] BAEL-1489: Applying suggested changes and updating to 2.0.0.RC2 --- spring-5-security/pom.xml | 2 +- .../BaeldungPasswordEncoderSetup.java | 22 ++++------- .../PasswordStorageWebSecurityConfigurer.java | 37 +++++++++---------- 3 files changed, 27 insertions(+), 34 deletions(-) diff --git a/spring-5-security/pom.xml b/spring-5-security/pom.xml index 0a1d1f5df0..ffe6865704 100644 --- a/spring-5-security/pom.xml +++ b/spring-5-security/pom.xml @@ -12,7 +12,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.0.M7 + 2.0.0.RC2 diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java index 94edf85631..94987029db 100644 --- a/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java +++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java @@ -2,12 +2,9 @@ package com.baeldung.passwordstorage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationEventPublisher; -import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.event.AuthenticationSuccessEvent; import org.springframework.security.core.Authentication; @@ -18,23 +15,20 @@ public class BaeldungPasswordEncoderSetup { private final static Logger LOG = LoggerFactory.getLogger(BaeldungPasswordEncoderSetup.class); - @Bean - public AuthenticationEventPublisher authenticationEventPublisher(final ApplicationEventPublisher publisher) { - return new DefaultAuthenticationEventPublisher(publisher); - } - @Bean public ApplicationListener authenticationSuccessListener(final PasswordEncoder encoder) { + return (AuthenticationSuccessEvent event) -> { - final Authentication authentication = event.getAuthentication(); + final Authentication auth = event.getAuthentication(); - if (authentication instanceof UsernamePasswordAuthenticationToken && authentication.getCredentials() != null) { - final CharSequence clearTextPassword = (CharSequence) authentication.getCredentials(); // 1 - final String newPasswordHash = encoder.encode(clearTextPassword); // 2 + if (auth instanceof UsernamePasswordAuthenticationToken && auth.getCredentials() != null) { - LOG.info("New password hash {} for user {}", newPasswordHash, authentication.getName()); + final CharSequence clearTextPass = (CharSequence) auth.getCredentials(); // 1 + final String newPasswordHash = encoder.encode(clearTextPass); // 2 - ((UsernamePasswordAuthenticationToken) authentication).eraseCredentials(); // 3 + LOG.info("New password hash {} for user {}", newPasswordHash, auth.getName()); + + ((UsernamePasswordAuthenticationToken) auth).eraseCredentials(); // 3 } }; } diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java index 0773de4bd6..22ef2f0835 100644 --- a/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java +++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java @@ -1,54 +1,53 @@ package com.baeldung.passwordstorage; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.DelegatingPasswordEncoder; -import org.springframework.security.crypto.password.MessageDigestPasswordEncoder; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.crypto.password.StandardPasswordEncoder; import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @Configuration public class PasswordStorageWebSecurityConfigurer extends WebSecurityConfigurerAdapter { - private final AuthenticationEventPublisher eventPublisher; - private final UserDetailsService userDetailsService; - - @Autowired - public PasswordStorageWebSecurityConfigurer(AuthenticationEventPublisher eventPublisher, UserDetailsService userDetailsService) { - this.eventPublisher = eventPublisher; - this.userDetailsService = userDetailsService; - } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.eraseCredentials(false) // 4 - .authenticationEventPublisher(eventPublisher) - .userDetailsService(userDetailsService) + .userDetailsService(getUserDefaultDetailsService()) .passwordEncoder(passwordEncoder()); } + @Bean + public UserDetailsService getUserDefaultDetailsService() { + User testUser = new User("baeldung", "{noop}SpringSecurity5", Collections.emptyList()); + return new InMemoryUserDetailsManager(testUser); + } + @Bean public PasswordEncoder passwordEncoder() { // set up the list of supported encoders and their prefixes - String encodingId = "bcrypt"; + PasswordEncoder defaultEncoder = new StandardPasswordEncoder(); Map encoders = new HashMap<>(); - encoders.put(encodingId, new BCryptPasswordEncoder()); + encoders.put("bcrypt", new BCryptPasswordEncoder()); encoders.put("scrypt", new SCryptPasswordEncoder()); - encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256")); + encoders.put("noop", NoOpPasswordEncoder.getInstance()); - DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(encodingId, encoders); - delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(encoders.get(encodingId)); + DelegatingPasswordEncoder passwordEncoder = new DelegatingPasswordEncoder("bcrypt", encoders); + passwordEncoder.setDefaultPasswordEncoderForMatches(defaultEncoder); - return delegatingPasswordEncoder; + return passwordEncoder; } }