JAVA-12754: Moved 2 articles to spring-security-web-rest-basic-auth

This commit is contained in:
sampadawagde 2022-07-18 20:27:20 +05:30
parent 8faf52f363
commit 3910819834
9 changed files with 255 additions and 18 deletions

View File

@ -10,28 +10,29 @@
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>parent-spring-5</artifactId> <artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-spring-5</relativePath> <relativePath>../../parent-boot-2</relativePath>
</parent> </parent>
<dependencies> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security --> <!-- Spring Security -->
<dependency> <dependency>
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId> <artifactId>spring-security-web</artifactId>
<version>${spring-security.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId> <artifactId>spring-security-config</artifactId>
<version>${spring-security.version}</version>
</dependency> </dependency>
<!-- Spring --> <!-- Spring -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId> <artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
@ -42,59 +43,48 @@
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId> <artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId> <artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId> <artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId> <artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId> <artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId> <artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId> <artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId> <artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId> <artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency> </dependency>
<!-- marshalling --> <!-- marshalling -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency> </dependency>
<!-- http --> <!-- http -->
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId> <artifactId>httpcore</artifactId>
<version>${httpcore.version}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
@ -105,7 +95,6 @@
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
@ -136,7 +125,6 @@
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId> <artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -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);
}
}

View File

@ -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<String> publicHello() {
return Arrays.asList("Hello", "World", "from", "Public");
}
@GetMapping("/private/hello")
public List<String> privateHello() {
return Arrays.asList("Hello", "World", "from", "Private");
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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<AuthenticationSuccessEvent> 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
}
};
}
}

View File

@ -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);
}
}

View File

@ -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<String, PasswordEncoder> 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;
}
}

View File

@ -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<String> result = template.getForEntity("/public/hello", String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
}
@Test
public void givenRequestOnPrivateService_shouldFailWith401() throws Exception {
ResponseEntity<String> result = template.getForEntity("/private/hello", String.class);
assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode());
}
@Test
public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception {
ResponseEntity<String> result = template.withBasicAuth("spring", "secret")
.getForEntity("/private/hello", String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
}
@Test
public void givenInvalidAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception {
ResponseEntity<String> result = template.withBasicAuth("spring", "wrong")
.getForEntity("/private/hello", String.class);
assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode());
}
}