Add ":servlet:spring-boot:java:oauth2:webclient"

This commit is contained in:
Rob Winch
2020-08-25 14:30:42 -05:00
parent 250c7cb86a
commit b15c37b72b
22 changed files with 1140 additions and 1 deletions
@@ -0,0 +1,35 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
* The index controller.
*
* @author Rob Winch
*/
@Controller
public class IndexController {
@GetMapping("/")
String index() {
return "index";
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration;
/**
* An OAuth web application that demonstrates integration with WebClient.
*
* @author Joe Grandja
*/
// FIXME: Work around https://github.com/spring-projects/spring-boot/issues/14463
@SpringBootApplication(exclude = ReactiveOAuth2ClientAutoConfiguration.class)
public class OAuth2WebClientApplication {
public static void main(String[] args) {
SpringApplication.run(OAuth2WebClientApplication.class, args);
}
}
@@ -0,0 +1,69 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.reactive.function.client.WebClient;
import static org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId;
/**
* Demonstrates use of WebClient.
*
* @author Joe Grandja
* @author Rob Winch
*/
@Controller
@RequestMapping(path = { "/webclient", "/public/webclient" })
public class OAuth2WebClientController {
private final WebClient webClient;
public OAuth2WebClientController(WebClient webClient) {
this.webClient = webClient;
}
@GetMapping("/explicit")
String explicit(Model model) {
// @formatter:off
String body = this.webClient
.get()
.attributes(clientRegistrationId("client-id"))
.retrieve()
.bodyToMono(String.class)
.block();
// @formatter:on
model.addAttribute("body", body);
return "response";
}
@GetMapping("/implicit")
String implicit(Model model) {
// @formatter:off
String body = this.webClient
.get()
.retrieve()
.bodyToMono(String.class)
.block();
// @formatter:on
model.addAttribute("body", body);
return "response";
}
}
@@ -0,0 +1,73 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.reactive.function.client.WebClient;
import static org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient;
/**
* Demonstrates of {@link RegisteredOAuth2AuthorizedClient}.
*
* @author Joe Grandja
* @author Rob Winch
*/
@Controller
@RequestMapping(path = { "/annotation", "/public/annotation" })
public class RegisteredOAuth2AuthorizedClientController {
private final WebClient webClient;
public RegisteredOAuth2AuthorizedClientController(WebClient webClient) {
this.webClient = webClient;
}
@GetMapping("/explicit")
String explicit(Model model,
@RegisteredOAuth2AuthorizedClient("client-id") OAuth2AuthorizedClient authorizedClient) {
// @formatter:off
String body = this.webClient
.get()
.attributes(oauth2AuthorizedClient(authorizedClient))
.retrieve()
.bodyToMono(String.class)
.block();
// @formatter:on
model.addAttribute("body", body);
return "response";
}
@GetMapping("/implicit")
String implicit(Model model, @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient) {
// @formatter:off
String body = this.webClient
.get()
.attributes(oauth2AuthorizedClient(authorizedClient))
.retrieve()
.bodyToMono(String.class)
.block();
// @formatter:on
model.addAttribute("body", body);
return "response";
}
}
@@ -0,0 +1,63 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import org.springframework.context.annotation.Bean;
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;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import static org.springframework.security.config.Customizer.withDefaults;
/**
* Security configuration for OAuth WebClient.
*
* @author Joe Grandja
*/
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests((requests) -> requests
.mvcMatchers("/", "/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(withDefaults())
.oauth2Login(withDefaults())
.oauth2Client(withDefaults());
// @formatter:on
}
@Bean
public UserDetailsService userDetailsService() {
// @formatter:off
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
// @formatter:on
return new InMemoryUserDetailsManager(userDetails);
}
}
@@ -0,0 +1,75 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
/**
* Configuration of WebClient so it works with OAuth2.
*
* @author Rob Winch
* @since 5.1
*/
@Configuration
public class WebClientConfiguration {
@Value("${resource-uri}")
String resourceUri;
@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
authorizedClientManager);
oauth2.setDefaultOAuth2AuthorizedClient(true);
// @formatter:off
return WebClient.builder()
.baseUrl(this.resourceUri)
.apply(oauth2.oauth2Configuration())
.build();
// @formatter:on
}
@Bean
OAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
// @formatter:off
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode()
.refreshToken()
.clientCredentials()
.password()
.build();
// @formatter:on
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
}
@@ -0,0 +1,21 @@
logging:
level:
root: INFO
org.springframework.web: INFO
org.springframework.security: INFO
# org.springframework.boot.autoconfigure: DEBUG
spring:
thymeleaf:
cache: false
security:
oauth2:
client:
registration:
client-id:
client-id: replace-with-client-id
client-secret: replace-with-client-secret
provider: github
scope: read:user,public_repo
resource-uri: https://api.github.com/user/repos
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<title>OAuth2 WebClient Showcase</title>
<meta charset="utf-8" />
</head>
<body>
<a th:href="@{/logout}">Log Out</a>
<h1>Examples</h1>
<h2>@RegisteredOAuth2AuthorizedClient</h2>
<p>
Examples on RegisteredOAuth2AuthorizedClientController
<h3>Authenticated</h3>
<ul>
<li><a th:href="@{/annotation/explicit}">Explicit</a> - Explicitly provide a Client Registration Id</li>
<li>
<a th:href="@{/annotation/implicit}">Implicit</a> - Use the currently logged in user's OAuth Token. This will
only work if the user authenticates with oauth2Login and the token provided is the correct token provided at
log in is authorized.</li>
</ul>
<h3>Public</h3>
<ul>
<li><a th:href="@{/public/annotation/explicit}">Explicit</a> - Explicitly provide a Client Registration Id</li>
<li>
<a th:href="@{/public/annotation/implicit}">Implicit</a> - This will fail if the user is not authenticated.
Since it is mapped to permitAll, it is going to fail unless the user already took an action to log in and then
authenticates with oauth2Login()</li>
</ul>
<h2>ServletOAuth2AuthorizedClientExchangeFilterFunction</h2>
<p>
Examples on OAuth2WebClientController that demonstrate how to use ServletOAuth2AuthorizedClientExchangeFilterFunction
<h3>Authenticated</h3>
<ul>
<li><a th:href="@{/webclient/explicit}">Explicit</a> - Explicitly provide a Client Registration Id</li>
<li>
<a th:href="@{/webclient/implicit}">Implicit</a> - Use the currently logged in user's OAuth Token. This will
only work if the user authenticates with oauth2Login and the token provided is the correct token provided at
log in is authorized.</li>
</ul>
<h3>Public</h3>
<ul>
<li><a th:href="@{/public/webclient/explicit}">Explicit</a> - Explicitly provide a Client Registration Id</li>
<li>
<a th:href="@{/public/webclient/implicit}">Implicit</a> - This will fail if the user is not authenticated.
Since it is mapped to permitAll, it is going to fail unless the user already took an action to log in and then
authenticates with oauth2Login()</li>
</ul>
</body>
</html>
@@ -0,0 +1,31 @@
<!--
~ Copyright 2002-2018 the original author or authors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<title>OAuth2 WebClient Showcase</title>
<meta charset="utf-8" />
</head>
<body>
<a th:href="@{/}">Back</a>
<h1>Response</h1>
<pre><code id="json" class="json" th:text="${body}"></code></pre>
<script>
json.innerHTML = JSON.stringify(JSON.parse(json.innerHTML), null, 4);
</script>
</body>
</html>
@@ -0,0 +1,47 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Rob Winch
*/
@SpringBootTest
@AutoConfigureMockMvc
public class OAuth2WebClientApplicationTests {
@Autowired
private MockMvc mockMvc;
@Test
void annotationExplicitWhenNotAuthenticatedThenLoginRequested() throws Exception {
// @formatter:off
this.mockMvc.perform(get("/annotation/explicit"))
.andExpect(status().is3xxRedirection());
// @formatter:on
}
}
@@ -0,0 +1,116 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.reactive.function.client.WebClient;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oauth2Client;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oauth2Login;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest
@Import({ SecurityConfiguration.class, OAuth2WebClientController.class })
@AutoConfigureMockMvc
public class OAuth2WebClientControllerTests {
private static MockWebServer web = new MockWebServer();
@Autowired
private MockMvc mockMvc;
@MockBean
ClientRegistrationRepository clientRegistrationRepository;
@AfterAll
static void shutdown() throws Exception {
web.shutdown();
}
@Test
void explicitWhenAuthenticatedThenUsesClientIdRegistration() throws Exception {
web.enqueue(new MockResponse().setBody("body").setResponseCode(200));
// @formatter:off
this.mockMvc.perform(get("/webclient/explicit")
.with(oauth2Login())
.with(oauth2Client("client-id")))
.andExpect(status().isOk());
// @formatter:on
}
@Test
void implicitWhenAuthenticatedThenUsesDefaultRegistration() throws Exception {
web.enqueue(new MockResponse().setBody("body").setResponseCode(200));
// @formatter:off
this.mockMvc.perform(get("/webclient/implicit")
.with(oauth2Login()))
.andExpect(status().isOk());
// @formatter:on
}
@Test
void publicExplicitWhenAuthenticatedThenUsesClientIdRegistration() throws Exception {
web.enqueue(new MockResponse().setBody("body").setResponseCode(200));
// @formatter:off
this.mockMvc.perform(get("/public/webclient/explicit")
.with(oauth2Client("client-id")))
.andExpect(status().isOk());
// @formatter:on
}
@Test
void publicImplicitWhenAuthenticatedThenUsesDefaultRegistration() throws Exception {
web.enqueue(new MockResponse().setBody("body").setResponseCode(200));
// @formatter:off
this.mockMvc.perform(get("/public/webclient/implicit")
.with(oauth2Login()))
.andExpect(status().isOk());
// @formatter:on
}
@Configuration
static class WebClientConfig {
@Bean
WebClient web() {
return WebClient.create(web.url("/").toString());
}
@Bean
OAuth2AuthorizedClientRepository authorizedClientRepository() {
return new HttpSessionOAuth2AuthorizedClientRepository();
}
}
}
@@ -0,0 +1,116 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.reactive.function.client.WebClient;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oauth2Client;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oauth2Login;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest
@Import({ SecurityConfiguration.class, RegisteredOAuth2AuthorizedClientController.class })
@AutoConfigureMockMvc
public class RegisteredOAuth2AuthorizedClientControllerTests {
private static MockWebServer web = new MockWebServer();
@Autowired
private MockMvc mockMvc;
@MockBean
ClientRegistrationRepository clientRegistrationRepository;
@AfterAll
static void shutdown() throws Exception {
web.shutdown();
}
@Test
void annotationExplicitWhenAuthenticatedThenUsesClientIdRegistration() throws Exception {
web.enqueue(new MockResponse().setBody("body").setResponseCode(200));
// @formatter:off
this.mockMvc.perform(get("/annotation/explicit")
.with(oauth2Login())
.with(oauth2Client("client-id")))
.andExpect(status().isOk());
// @formatter:on
}
@Test
void annotationImplicitWhenAuthenticatedThenUsesDefaultRegistration() throws Exception {
web.enqueue(new MockResponse().setBody("body").setResponseCode(200));
// @formatter:off
this.mockMvc.perform(get("/annotation/implicit")
.with(oauth2Login()))
.andExpect(status().isOk());
// @formatter:on
}
@Test
void publicAnnotationExplicitWhenAuthenticatedThenUsesClientIdRegistration() throws Exception {
web.enqueue(new MockResponse().setBody("body").setResponseCode(200));
// @formatter:off
this.mockMvc.perform(get("/public/annotation/explicit")
.with(oauth2Client("client-id")))
.andExpect(status().isOk());
// @formatter:on
}
@Test
void publicAnnotationImplicitWhenAuthenticatedThenUsesDefaultRegistration() throws Exception {
web.enqueue(new MockResponse().setBody("body").setResponseCode(200));
// @formatter:off
this.mockMvc.perform(get("/public/annotation/implicit")
.with(oauth2Login()))
.andExpect(status().isOk());
// @formatter:on
}
@Configuration
static class WebClientConfig {
@Bean
WebClient web() {
return WebClient.create(web.url("/").toString());
}
@Bean
OAuth2AuthorizedClientRepository authorizedClientRepository() {
return new HttpSessionOAuth2AuthorizedClientRepository();
}
}
}