Implement protected resource call flow in oauth2login sample
Fixes gh-4362
This commit is contained in:
parent
e5eda24054
commit
ae17cc255b
|
@ -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'
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> </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>
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue