diff --git a/spring-5-reactive-oauth/pom.xml b/spring-5-reactive-oauth/pom.xml new file mode 100644 index 0000000000..72e0659bf0 --- /dev/null +++ b/spring-5-reactive-oauth/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + com.baeldung.reactive.oauth + spring-5-reactive-oauth + 1.0.0-SNAPSHOT + jar + + spring-5-reactive-oauth + WebFluc and Spring Security OAuth + + + org.springframework.boot + spring-boot-starter-parent + 2.1.0.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.security + spring-security-oauth2-client + + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + org.springframework.security + spring-security-test + test + + + + diff --git a/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/SecurityConfig.java b/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/SecurityConfig.java new file mode 100644 index 0000000000..2fa1dd9380 --- /dev/null +++ b/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/SecurityConfig.java @@ -0,0 +1,19 @@ +package com.baeldung.reactive.oauth; + +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.web.server.SecurityWebFilterChain; + +@EnableWebFluxSecurity +public class SecurityConfig { + + @Bean + public SecurityWebFilterChain configure(ServerHttpSecurity http) throws Exception { + return http.authorizeExchange() + .pathMatchers("/about").permitAll() + .anyExchange().authenticated() + .and().oauth2Login() + .and().build(); + } +} diff --git a/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/Spring5ReactiveOauthApplication.java b/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/Spring5ReactiveOauthApplication.java new file mode 100644 index 0000000000..602ded6b9e --- /dev/null +++ b/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/Spring5ReactiveOauthApplication.java @@ -0,0 +1,25 @@ +package com.baeldung.reactive.oauth; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction; +import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; +import org.springframework.web.reactive.function.client.WebClient; + +@SpringBootApplication +public class Spring5ReactiveOauthApplication { + + public static void main(String[] args) { + SpringApplication.run(Spring5ReactiveOauthApplication.class, args); + } + + @Bean + public WebClient webClient(ReactiveClientRegistrationRepository clientRegistrationRepo, ServerOAuth2AuthorizedClientRepository authorizedClientRepo) { + ServerOAuth2AuthorizedClientExchangeFilterFunction filter = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepo, authorizedClientRepo); + return WebClient.builder() + .filter(filter) + .build(); + } +} diff --git a/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/web/MainController.java b/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/web/MainController.java new file mode 100644 index 0000000000..b3ce24b0ea --- /dev/null +++ b/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/web/MainController.java @@ -0,0 +1,46 @@ +package com.baeldung.reactive.oauth.web; + +import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; +import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.reactive.function.client.WebClient; + +import reactor.core.publisher.Mono; + +import com.baeldung.reactive.oauth.web.dto.Foo; + +@RestController +public class MainController { + + @Autowired + private WebClient webClient; + + @GetMapping("/") + public Mono index(@AuthenticationPrincipal Mono oauth2User) { + return oauth2User + .map(OAuth2User::getName) + .map(name -> String.format("Hi, %s", name)); + } + + @GetMapping("/foos/{id}") + public Mono getFooResource(@RegisteredOAuth2AuthorizedClient("custom") OAuth2AuthorizedClient client, @PathVariable final long id){ + return webClient + .get() + .uri("http://localhost:8088/spring-security-oauth-resource/foos/{id}", id) + .attributes(oauth2AuthorizedClient(client)) + .retrieve() + .bodyToMono(Foo.class); + } + + @GetMapping("/about") + public String getAboutPage() { + return "WebFlux OAuth example"; + } +} diff --git a/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/web/dto/Foo.java b/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/web/dto/Foo.java new file mode 100644 index 0000000000..15b4addbcd --- /dev/null +++ b/spring-5-reactive-oauth/src/main/java/com/baeldung/reactive/oauth/web/dto/Foo.java @@ -0,0 +1,35 @@ +package com.baeldung.reactive.oauth.web.dto; + +public class Foo { + private long id; + private String name; + + public Foo() { + super(); + } + + public Foo(final long id, final String name) { + super(); + + this.id = id; + this.name = name; + } + + // + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } +} diff --git a/spring-5-reactive-oauth/src/main/resources/application.yml b/spring-5-reactive-oauth/src/main/resources/application.yml new file mode 100644 index 0000000000..e35e19b344 --- /dev/null +++ b/spring-5-reactive-oauth/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + security: + oauth2: + client: + registration: + google: + client-id: YOUR_APP_CLIENT_ID + client-secret: YOUR_APP_CLIENT_SECRET + custom: + client-id: fooClientIdPassword + client-secret: secret + scopes: read,foo + authorization-grant-type: authorization_code + redirect-uri-template: http://localhost:8080/login/oauth2/code/custom + provider: + custom: + authorization-uri: http://localhost:8081/spring-security-oauth-server/oauth/authorize + token-uri: http://localhost:8081/spring-security-oauth-server/oauth/token + user-info-uri: http://localhost:8088/spring-security-oauth-resource/users/extra + user-name-attribute: user_name \ No newline at end of file diff --git a/spring-5-reactive-oauth/src/test/java/com/baeldung/reactive/oauth/Spring5ReactiveOauthIntegrationTest.java b/spring-5-reactive-oauth/src/test/java/com/baeldung/reactive/oauth/Spring5ReactiveOauthIntegrationTest.java new file mode 100644 index 0000000000..db545d63de --- /dev/null +++ b/spring-5-reactive-oauth/src/test/java/com/baeldung/reactive/oauth/Spring5ReactiveOauthIntegrationTest.java @@ -0,0 +1,16 @@ +package com.baeldung.reactive.oauth; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class Spring5ReactiveOauthIntegrationTest { + + @Test + public void contextLoads() { + } + +}