Quellcode durchsuchen

Implement protected resource call flow in oauth2login sample

Fixes gh-4362
Joe Grandja vor 8 Jahren
Ursprung
Commit
ae17cc255b

+ 2 - 0
samples/boot/oauth2login/spring-security-samples-boot-oauth2login.gradle

@@ -3,9 +3,11 @@ apply plugin: 'io.spring.convention.spring-sample-boot'
 dependencies {
 	compile project(':spring-security-config')
 	compile project(':spring-security-oauth2-client')
+	compile 'org.springframework:spring-webflux'
 	compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
 	compile 'org.springframework.boot:spring-boot-starter-web'
 	compile 'org.thymeleaf.extras:thymeleaf-extras-springsecurity4'
+	compile 'io.projectreactor.ipc:reactor-netty'
 
 	testCompile project(':spring-security-test')
 	testCompile 'net.sourceforge.htmlunit:htmlunit'

+ 6 - 6
samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java

@@ -98,7 +98,7 @@ public class OAuth2LoginApplicationTests {
 	}
 
 	@Test
-	public void requestRootPageWhenNotAuthenticatedThenDisplayLoginPage() throws Exception {
+	public void requestIndexPageWhenNotAuthenticatedThenDisplayLoginPage() throws Exception {
 		HtmlPage page = this.webClient.getPage("/");
 		this.assertLoginPage(page);
 	}
@@ -158,7 +158,7 @@ public class OAuth2LoginApplicationTests {
 	}
 
 	@Test
-	public void requestAuthorizationCodeGrantWhenValidAuthorizationResponseThenDisplayUserInfoPage() throws Exception {
+	public void requestAuthorizationCodeGrantWhenValidAuthorizationResponseThenDisplayIndexPage() throws Exception {
 		HtmlPage page = this.webClient.getPage("/");
 
 		HtmlAnchor clientAnchorElement = this.getClientAnchorElement(page, this.githubClientRegistration);
@@ -181,7 +181,7 @@ public class OAuth2LoginApplicationTests {
 						.build().encode().toUriString();
 
 		page = this.webClient.getPage(new URL(authorizationResponseUri));
-		this.assertUserInfoPage(page);
+		this.assertIndexPage(page);
 	}
 
 	@Test
@@ -324,12 +324,12 @@ public class OAuth2LoginApplicationTests {
 		}
 	}
 
-	private void assertUserInfoPage(HtmlPage page) throws Exception {
-		assertThat(page.getTitleText()).isEqualTo("Spring Security - OAuth2 User Info");
+	private void assertIndexPage(HtmlPage page) throws Exception {
+		assertThat(page.getTitleText()).isEqualTo("Spring Security - OAuth 2.0 Login");
 
 		DomNodeList<HtmlElement> divElements = page.getBody().getElementsByTagName("div");
 		assertThat(divElements.get(1).asText()).contains("User: joeg@springsecurity.io");
-		assertThat(divElements.get(4).asText()).contains("Name: joeg@springsecurity.io");
+		assertThat(divElements.get(4).asText()).contains("You are successfully logged in joeg@springsecurity.io");
 	}
 
 	private HtmlAnchor getClientAnchorElement(HtmlPage page, ClientRegistration clientRegistration) {

+ 35 - 2
samples/boot/oauth2login/src/main/java/sample/web/MainController.java

@@ -15,22 +15,55 @@
  */
 package sample.web;
 
+import org.springframework.http.HttpHeaders;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
 import org.springframework.security.oauth2.core.user.OAuth2User;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.reactive.function.client.ClientRequest;
+import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+
+import java.util.Map;
 
 /**
  * @author Joe Grandja
  */
 @Controller
 public class MainController {
+	private WebClient webClient = WebClient.create();
+
 
 	@RequestMapping("/")
-	public String index(Model model, @AuthenticationPrincipal OAuth2User user) {
+	public String index(Model model, @AuthenticationPrincipal OAuth2User user, OAuth2AuthenticationToken authentication) {
 		model.addAttribute("userName", user.getName());
-		model.addAttribute("userAttributes", user.getAttributes());
+		model.addAttribute("clientName", authentication.getClientRegistration().getClientName());
 		return "index";
 	}
+
+	@RequestMapping("/userinfo")
+	public String userinfo(Model model, OAuth2AuthenticationToken authentication) {
+		Map userAttributes = this.webClient
+			.filter(oauth2Credentials(authentication))
+			.get()
+			.uri(authentication.getClientRegistration().getProviderDetails().getUserInfoUri())
+			.retrieve()
+			.bodyToMono(Map.class)
+			.block();
+		model.addAttribute("userAttributes", userAttributes);
+		return "userinfo";
+	}
+
+	private ExchangeFilterFunction oauth2Credentials(OAuth2AuthenticationToken authentication) {
+		return ExchangeFilterFunction.ofRequestProcessor(
+			clientRequest -> {
+				ClientRequest authorizedRequest = ClientRequest.from(clientRequest)
+					.header(HttpHeaders.AUTHORIZATION, "Bearer " + authentication.getAccessToken().getTokenValue())
+					.build();
+				return Mono.just(authorizedRequest);
+			});
+	}
 }

+ 5 - 9
samples/boot/oauth2login/src/main/resources/templates/index.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
 <head>
-	<title>Spring Security - OAuth2 User Info</title>
+	<title>Spring Security - OAuth 2.0 Login</title>
 	<meta charset="utf-8" />
 </head>
 <body>
@@ -16,18 +16,14 @@
 		</form>
 	</div>
 </div>
-<h1>OAuth2 User Info</h1>
+<h1>OAuth 2.0 Login with Spring Security</h1>
 <div>
-	<span style="font-weight:bold">Name: </span><span th:text="${userName}"></span>
+	You are successfully logged in <span style="font-weight:bold" th:text="${userName}"></span>
+	via the OAuth 2.0 Client <span style="font-weight:bold" th:text="${clientName}"></span>
 </div>
 <div>&nbsp;</div>
 <div>
-	<span style="font-weight:bold">Attributes:</span>
-	<ul>
-		<li th:each="userAttribute : ${userAttributes}">
-			<span style="font-weight:bold" th:text="${userAttribute.key}"></span>: <span th:text="${userAttribute.value}"></span>
-		</li>
-	</ul>
+	<a href="/userinfo" th:href="@{/userinfo}">Display User Info</a>
 </div>
 </body>
 </html>

+ 19 - 0
samples/boot/oauth2login/src/main/resources/templates/userinfo.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
+<head>
+	<title>Spring Security - OAuth 2.0 User Info</title>
+	<meta charset="utf-8" />
+</head>
+<body>
+<div th:substituteby="index::logout"></div>
+<h1>OAuth 2.0 User Info</h1>
+<div>
+	<span style="font-weight:bold">User Attributes:</span>
+	<ul>
+		<li th:each="userAttribute : ${userAttributes}">
+			<span style="font-weight:bold" th:text="${userAttribute.key}"></span>: <span th:text="${userAttribute.value}"></span>
+		</li>
+	</ul>
+</div>
+</body>
+</html>