diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml b/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml
index 30b92be5ac..41f508c1a3 100644
--- a/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml
@@ -10,28 +10,29 @@
com.baeldung
- parent-spring-5
+ parent-boot-2
0.0.1-SNAPSHOT
- ../../parent-spring-5
+ ../../parent-boot-2
+
+ org.springframework.boot
+ spring-boot-starter-web
+
org.springframework.security
spring-security-web
- ${spring-security.version}
org.springframework.security
spring-security-config
- ${spring-security.version}
org.springframework
spring-core
- ${spring.version}
commons-logging
@@ -42,59 +43,48 @@
org.springframework
spring-context
- ${spring.version}
org.springframework
spring-jdbc
- ${spring.version}
org.springframework
spring-beans
- ${spring.version}
org.springframework
spring-aop
- ${spring.version}
org.springframework
spring-tx
- ${spring.version}
org.springframework
spring-expression
- ${spring.version}
org.springframework
spring-web
- ${spring.version}
org.springframework
spring-webmvc
- ${spring.version}
org.springframework
spring-oxm
- ${spring.version}
com.fasterxml.jackson.core
jackson-databind
- ${jackson.version}
org.apache.httpcomponents
httpcore
- ${httpcore.version}
commons-logging
@@ -105,7 +95,6 @@
org.apache.httpcomponents
httpclient
- ${httpclient.version}
commons-logging
@@ -136,7 +125,6 @@
org.springframework
spring-test
- ${spring.version}
test
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthApplication.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthApplication.java
new file mode 100644
index 0000000000..6ccfd04553
--- /dev/null
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthApplication.java
@@ -0,0 +1,14 @@
+package com.baeldung.inmemory;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class InMemoryAuthApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(InMemoryAuthApplication.class, args);
+ }
+
+
+}
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthController.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthController.java
new file mode 100644
index 0000000000..ff7ae9a131
--- /dev/null
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthController.java
@@ -0,0 +1,21 @@
+package com.baeldung.inmemory;
+
+import java.util.Arrays;
+import java.util.List;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class InMemoryAuthController {
+
+ @GetMapping("/public/hello")
+ public List publicHello() {
+ return Arrays.asList("Hello", "World", "from", "Public");
+ }
+
+ @GetMapping("/private/hello")
+ public List privateHello() {
+ return Arrays.asList("Hello", "World", "from", "Private");
+ }
+
+}
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java
new file mode 100644
index 0000000000..4b32a1126e
--- /dev/null
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java
@@ -0,0 +1,34 @@
+package com.baeldung.inmemory;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.factory.PasswordEncoderFactories;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@Configuration
+public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
+ auth.inMemoryAuthentication()
+ .passwordEncoder(encoder)
+ .withUser("spring")
+ .password(encoder.encode("secret"))
+ .roles("USER");
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.authorizeRequests()
+ .antMatchers("/private/**")
+ .authenticated()
+ .antMatchers("/public/**")
+ .permitAll()
+ .and()
+ .httpBasic();
+ }
+
+}
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java
new file mode 100644
index 0000000000..4b6494f666
--- /dev/null
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java
@@ -0,0 +1,29 @@
+package com.baeldung.inmemory;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+//@Configuration
+public class InMemoryNoOpAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.inMemoryAuthentication()
+ .withUser("spring")
+ .password("{noop}secret")
+ .roles("USER");
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.authorizeRequests()
+ .antMatchers("/private/**")
+ .authenticated()
+ .antMatchers("/public/**")
+ .permitAll()
+ .and()
+ .httpBasic();
+ }
+}
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java
new file mode 100644
index 0000000000..94987029db
--- /dev/null
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java
@@ -0,0 +1,35 @@
+package com.baeldung.passwordstorage;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+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;
+
+@Configuration
+public class BaeldungPasswordEncoderSetup {
+
+ private final static Logger LOG = LoggerFactory.getLogger(BaeldungPasswordEncoderSetup.class);
+
+ @Bean
+ public ApplicationListener authenticationSuccessListener(final PasswordEncoder encoder) {
+
+ return (AuthenticationSuccessEvent event) -> {
+ final Authentication auth = event.getAuthentication();
+
+ if (auth instanceof UsernamePasswordAuthenticationToken && auth.getCredentials() != null) {
+
+ final CharSequence clearTextPass = (CharSequence) auth.getCredentials(); // 1
+ final String newPasswordHash = encoder.encode(clearTextPass); // 2
+
+ LOG.info("New password hash {} for user {}", newPasswordHash, auth.getName());
+
+ ((UsernamePasswordAuthenticationToken) auth).eraseCredentials(); // 3
+ }
+ };
+ }
+}
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageApplication.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageApplication.java
new file mode 100644
index 0000000000..173d979a45
--- /dev/null
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/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-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java
new file mode 100644
index 0000000000..59a2ae1dc2
--- /dev/null
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java
@@ -0,0 +1,55 @@
+package com.baeldung.passwordstorage;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+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.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 {
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.eraseCredentials(false) // 4
+ .userDetailsService(getUserDefaultDetailsService())
+ .passwordEncoder(passwordEncoder());
+ }
+
+ @Bean
+ public UserDetailsService getUserDefaultDetailsService() {
+ return new InMemoryUserDetailsManager(User
+ .withUsername("baeldung")
+ .password("{noop}SpringSecurity5")
+ .authorities(Collections.emptyList())
+ .build());
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ // set up the list of supported encoders and their prefixes
+ PasswordEncoder defaultEncoder = new StandardPasswordEncoder();
+ Map encoders = new HashMap<>();
+ encoders.put("bcrypt", new BCryptPasswordEncoder());
+ encoders.put("scrypt", new SCryptPasswordEncoder());
+ encoders.put("noop", NoOpPasswordEncoder.getInstance());
+
+ DelegatingPasswordEncoder passwordEncoder = new DelegatingPasswordEncoder("bcrypt", encoders);
+ passwordEncoder.setDefaultPasswordEncoderForMatches(defaultEncoder);
+
+ return passwordEncoder;
+ }
+
+}
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/test/java/com/baeldung/inmemory/InMemoryAuthControllerIntegrationTest.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/test/java/com/baeldung/inmemory/InMemoryAuthControllerIntegrationTest.java
new file mode 100644
index 0000000000..9d08cb7cfa
--- /dev/null
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/test/java/com/baeldung/inmemory/InMemoryAuthControllerIntegrationTest.java
@@ -0,0 +1,48 @@
+package com.baeldung.inmemory;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = InMemoryAuthApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
+public class InMemoryAuthControllerIntegrationTest {
+
+ @Autowired
+ private TestRestTemplate template;
+
+ @Test
+ public void givenRequestOnPublicService_shouldSucceedWith200() throws Exception {
+ ResponseEntity result = template.getForEntity("/public/hello", String.class);
+ assertEquals(HttpStatus.OK, result.getStatusCode());
+ }
+
+ @Test
+ public void givenRequestOnPrivateService_shouldFailWith401() throws Exception {
+ ResponseEntity result = template.getForEntity("/private/hello", String.class);
+ assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode());
+ }
+
+ @Test
+ public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception {
+ ResponseEntity result = template.withBasicAuth("spring", "secret")
+ .getForEntity("/private/hello", String.class);
+ assertEquals(HttpStatus.OK, result.getStatusCode());
+ }
+
+ @Test
+ public void givenInvalidAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception {
+ ResponseEntity result = template.withBasicAuth("spring", "wrong")
+ .getForEntity("/private/hello", String.class);
+ assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode());
+ }
+
+}