diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java new file mode 100644 index 0000000000..1a89c362cd --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java @@ -0,0 +1,31 @@ +package org.baeldung.multipleauthproviders; + +import java.util.Collections; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.stereotype.Component; + +@Component +public class CustomAuthenticationProvider implements AuthenticationProvider { + @Override + public Authentication authenticate(Authentication auth) throws AuthenticationException { + final String username = auth.getName(); + final String password = auth.getCredentials() + .toString(); + + if ("externaluser".equals(username) && "pass".equals(password)) { + return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList()); + } else { + throw new BadCredentialsException("External system authentication failed"); + } + } + + @Override + public boolean supports(Class auth) { + return auth.equals(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java new file mode 100644 index 0000000000..80573c1c7d --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java @@ -0,0 +1,13 @@ +package org.baeldung.multipleauthproviders; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MultipleAuthController { + + @RequestMapping("/api/ping") + public String getPing() { + return "OK"; + } +} \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java new file mode 100644 index 0000000000..077f558bd2 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java @@ -0,0 +1,12 @@ +package org.baeldung.multipleauthproviders; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +// @ImportResource({ "classpath*:spring-security-multiple-auth-providers.xml" }) +public class MultipleAuthProvidersApplication { + public static void main(String[] args) { + SpringApplication.run(MultipleAuthProvidersApplication.class, args); + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java new file mode 100644 index 0000000000..432cc61e87 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java @@ -0,0 +1,34 @@ +package org.baeldung.multipleauthproviders; + +import org.springframework.beans.factory.annotation.Autowired; +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.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +public class MultipleAuthProvidersSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + CustomAuthenticationProvider customAuthProvider; + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + + auth.authenticationProvider(customAuthProvider); + + auth.inMemoryAuthentication() + .withUser("memuser") + .password("pass") + .roles("USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.httpBasic() + .and() + .authorizeRequests() + .antMatchers("/api/**") + .authenticated(); + } +} diff --git a/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml b/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml new file mode 100644 index 0000000000..4cfa6bbf26 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationTests.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationTests.java new file mode 100644 index 0000000000..0d70cd64e4 --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationTests.java @@ -0,0 +1,61 @@ +package org.baeldung.web; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; + +import org.baeldung.multipleauthproviders.MultipleAuthProvidersApplication; +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.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = MultipleAuthProvidersApplication.class) +public class MultipleAuthProvidersApplicationTests { + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void givenMemUsers_whenGetPingWithValidUser_thenOk() { + ResponseEntity result = makeRestCallToGetPing("memuser", "pass"); + + assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getBody()).isEqualTo("OK"); + } + + @Test + public void givenExternalUsers_whenGetPingWithValidUser_thenOK() { + ResponseEntity result = makeRestCallToGetPing("externaluser", "pass"); + + assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getBody()).isEqualTo("OK"); + } + + @Test + public void givenAuthProviders_whenGetPingWithNoCred_then401() { + ResponseEntity result = makeRestCallToGetPing(); + + assertThat(result.getStatusCodeValue()).isEqualTo(401); + } + + @Test + public void givenAuthProviders_whenGetPingWithBadCred_then401() { + ResponseEntity result = makeRestCallToGetPing("user", "bad_password"); + + assertThat(result.getStatusCodeValue()).isEqualTo(401); + } + + private ResponseEntity makeRestCallToGetPing(String username, String password) { + return restTemplate.withBasicAuth(username, password) + .getForEntity("/api/ping", String.class, Collections.emptyMap()); + } + + private ResponseEntity makeRestCallToGetPing() { + return restTemplate.getForEntity("/api/ping", String.class, Collections.emptyMap()); + } +}