Implement protected resource call flow in oauth2login sample

Fixes gh-4362
This commit is contained in:
Joe Grandja 2017-06-01 11:46:22 -04:00
parent e5eda24054
commit ae17cc255b
5 changed files with 67 additions and 17 deletions

View File

@ -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'

View File

@ -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) {

View File

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

View File

@ -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>

View File

@ -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>