Why is form login principal null inside an Iframe? - spring

I am trying to enable my Spring Boot website within an iframe. I have security config, request filter, form login and OAuth2. My form login works well from browser but as soon as I logged in from iframe I can see JSESSIONID is null for the same users logged in from browser.
Log for iframe:
UsernamePasswordAuthenticationToken [Principal=test#example.com, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_USER]]
Log for browser:
[Authentication=UsernamePasswordAuthenticationToken [Principal=test#example.com, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=04E5DB0982A859E5C215294EF96814FD], Granted Authorities=[ROLE_MANAGER, ROLE_USER]]]
Below is my security config:
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().disable()
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/app_resources/**", "/signup", "/favicon.ico", "/login", "/logout", "/signup",
"/oauth2/authorization/**", "/pages/**", "/login/oauth2/code/**", "/login/oauth2/code/**",
"/product/authenticate", "/cdnjs.cloudflare.com/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
.formLogin(form -> form
.loginPage("/auth")
.defaultSuccessUrl("/index")
.failureHandler(authenticationfailure())
.successHandler(new AuthSuccessHandler()).permitAll()
)
.logout(out -> out
.logoutUrl("/logout")
)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.authenticationProvider(authProvider())
.oauth2Login()
.loginPage("/auth")
.defaultSuccessUrl("/homesuccess")
.successHandler(new AuthSuccessHandler());
http
.headers()
.frameOptions().disable();
return http.build();
}
Below is my AuthenticationSuccesHandler:
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
System.out.println("onAuthenticationSuccess >>>>>>>>>>>>>>"+authentication.toString());
request.getSession(false).setMaxInactiveInterval(604800);
RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
redirectStrategy.sendRedirect(request, response, "/");
}
Not really sure what went wrong inside an iframe. I can see my login page, I can see the user password token object in AuthennticationSuccessHandler but after redirecting it to dashboard suddenly principal object becomes null in security filter.
MVC config:
#EnableWebMvc
#Configuration
public class MvcConfig implements WebMvcConfigurer{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
VersionResourceResolver versionResolver = new VersionResourceResolver().addContentVersionStrategy("/**/*.js",
"/**/*.css", "/**/*.png");
registry.addResourceHandler("/app_resources/**", "/favicon.ico", "/firebase-messaging-sw.js", "/manifest.json",
"/salesken.png")
.addResourceLocations("/assets/js/",
"/assets/css/","/assets/img/","/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.MINUTES)).resourceChain(true)
.addResolver(versionResolver);
}
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setPrefix("pages/");
bean.setSuffix(".jsp");
return bean;
}
}
Even when I am trying to put authentication object in session, this object is not set and its value is null in the request filter.

Chrome uses 'Lax' as the default same-site cookie policy. This prevents the browser for using the cookie in the iFrame.
To fix this by setting the SameSite flag to none with Spring Boot 2.5.0 on, add the following:
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration(proxyBeanMethods = false)
public class SameSiteNoneConfiguration {
#Bean
public CookieSameSiteSupplier applicationCookieSameSiteSupplier() {
return CookieSameSiteSupplier.ofNone();
}
}
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
Only works with https because the cookie must be secure. Spring Boot session cookies are already httpOnly.
Spring Boot pre-2.5.0 does not have a CookieSameSiteSupplier so the following must be created. Requires Spring Boot v2.1.0.RELEASE and up.
#Component
#AllArgsConstructor
public class SameSiteInjector {
private final ApplicationContext applicationContext;
#EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
DefaultCookieSerializer cookieSerializer = applicationContext.getBean(DefaultCookieSerializer.class);
cookieSerializer.setSameSite("none");
}
}
with the following dependency:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
To do this on Tomcat - from 8.5.42+. Edit %TOMCAT_HOME%/conf/context.xml, update CookieProcessor element on following lines say for setting SameSiteCookies in HTTP response headers's set-cookie.
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" sameSiteCookies="none" />
Because you are editing %TOMCAT_HOME%/conf/context.xml it will do this for all installed webapps. To avoid this you need to hack the META-INF folder and create a context.xml and put the above snippet within.

Related

SAML with Spring security anonymousUser

We have to implement SSO using SAML in SpringBoot. I have achieved to redirect the user to the identity provider login page and make the login. The problem is that after the login, when I try to get the user info with SecurityContextHolder.getContext().getAuthentication() I get anonymousUser, and not the logged user data.
Here is my SecurityConfig
#Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().and()
.authorizeRequests()
.antMatchers("/saml/**).permitAll()
.anyRequest().authenticated()
.and()
.apply(saml())
.userDetailsService(samlUserDetailsServiceImpl)
.serviceProvider()
.protocol("http")
.hostname("localhost:8080")
.basePath("/")
.keyStore()
.storeFilePath("classpath:metadata/samlKeystore.jks")
.keyPassword(keystorePass)
.keyname(keystoreAlias)
.and()
.and()
.identityProvider()
.metadataFilePath("classpath:metadata/idp.xml")
.discoveryEnabled(false)
.and()
.and();
And the implementation of SAMLUserDetailService
#Service
public class SamlUserServiceImpl implements SAMLUserDetailsService {
#Override
public Object loadUserBySAML(SAMLCredential credential) {
String userID = credential.getNameID().getValue();
GrantedAuthority userAuthority = new SimpleGrantedAuthority("ROLE_GESTOR");
return new User(userID, "DUMMY", Collections.singletonList(userAuthority));
}
I have debugged the code and in the SAMLUserDetailsService implementation I receive the user data after logging.
Also, is there a way to indicate the redirection url when the user has logged? Now it redirects to same url.
Thanks in advance

automate the OAuth2 refresh_token process with SpringBoot 2

I have a SpringBoot2 application, a MainApp as a resource-server, KeyCloak as AuthorizationServer and a maven module, which is related to the MainApp, as a OAuth2LoginClient.
In other words, in MavenModule I have the follow SecurityConfig:
#Configuration
#PropertySource("classpath:idm.properties")
public class Auth0Provider extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.requestMatchers(PROTECTED_URLS).authenticated()
.anyRequest().authenticated()
)
.oauth2Login().redirectionEndpoint().baseUri("/callback*");
http.csrf().disable();
}
private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
new AntPathRequestMatcher("/idmauth/**")
);
}
There is also a controller that intercepts the protected call:
#Value("${oauth.redirectURL}")
private String redirectURL;
#Autowired
private OAuth2AuthorizedClientService clientService;
#RequestMapping(method = RequestMethod.GET, path = "/redirect")
public RedirectView redirectWithUsingRedirectView(OAuth2AuthenticationToken oauthToken, RedirectAttributes attributes) {
OAuth2AuthorizedClient client =
clientService.loadAuthorizedClient(
oauthToken.getAuthorizedClientRegistrationId(),
oauthToken.getName());
String token = client.getAccessToken().getTokenValue();
attributes.addAttribute("jwt", token);
return new RedirectView(redirectURL);
}
This return the AccessToken to my frontend. Clearly in my idm.properties file I have the spring.oauth2.client.provider and spring.oauth2.client.registration info.
Now the MainApp is a SpringBoot2 WebApp with this simple SecurityConfig:
#EnableWebSecurity
#Configuration
public class Oauth2RestApiSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.requestMatchers().antMatchers("/api/**")
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.oauth2ResourceServer().jwt();
}
}
And in it's application.properties just the line:
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://<host>/protocol/openid-connect/certs
All works fine but, when the token expire, the only way I have currently found to refresh my token
is to manually do this HTTP-POST:
POST /auth/realms/<audience>/protocol/openid-connect/token HTTP/1.1
Host: <host>
Content-Type: application/x-www-form-urlencoded
Content-Length: 844
client_id=<my_client_id>
&client_secret=<my_client_secret>
&refresh_token=<refresh_token_previously_obtained>
&grant_type=refresh_token
Is there a better way to do this? Maybe inside the SecurityConfig or with a specific path inside spring.oauth2.x properties?
Note that refreshing an access token is done on the OAuth 2.0 client side.
This is done automatically by Spring Security if you have configured a WebClient to be used when requesting protected resources.
#Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
return WebClient.builder()
.apply(oauth2Client.oauth2Configuration())
.build();
}
When you have done so, the expired OAuth2AccessToken will be refreshed (or renewed) if an OAuth2AuthorizedClientProvider is available to perform the authorization.

Spring Security: oauth2Login redirect only on certain paths

I have Spring Security configured to authenticate my website, such that all paths are automatically redirected to the OAuth2 authorization URL (using .oauth2Login()). However, I want unauthenticated requests to the API (i.e. /api/**) to return 401 Unauthorized instead of being redirected. I can't figure out how to do this. Any help would be much appreciated.
Here is my current configuration:
http
.authorizeRequests()
.antMatchers("/api/auth/oauth2/callback").permitAll()
.anyRequest().authenticated()
.oauth2Login()
.authorizationEndpoint()
.baseUri(this.oauth2AuthorizationRedirectBaseUri);
http.logout()
.logoutUrl("/auth/logout")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
You can define a custom authentication entry point for /API/** and add t to your configuration:
#Component
public class CustomAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
#Override
public void commence(
HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
#Override
public void afterPropertiesSet() throws Exception {
setRealmName("developers");
super.afterPropertiesSet();
}
}
in your Http security configs add:
http.
...
.exceptionHandling()
.defaultAuthenticationEntryPointFor(
new CustomAuthenticationEntryPoint(),
new AntPathRequestMatcher("/api/**"))

How to scale horizontally a spring-boot oauth2 server with JDBC implementation

I have a spring boot oauth2 server that uses a JDBC implementation. It is configured as an authorization server with #EnableAuthorizationServer.
I'd like to scale that application horyzontally but it doesn't seem to work properly.
I can connect only if I have one instance (pods) of the server.
I use autorisation_code_client grant from another client service to get the token.
So first the client service redirect the user to the oauth2 server form, then once the user is authenticated he is supposed to be redirect to the client-service with a code attached to the url, finally the client use that code to request the oauth2 server again and obtain the token.
Here the user is not redirected at all if I have several instance of the oauth2-server. With one instance it works well.
When I check the log of the two instances in real time, I can see that the authentication works on one of them. I don't have any specific error the user is just not redirected.
Is there a way to configure the oauth2-server to be stateless or other way to fix that issue ?
Here is my configuration, the AuthorizationServerConfigurerAdapter implementation.
#Configuration
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Bean
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource oauthDataSource() {
return DataSourceBuilder.create().build();
}
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Bean
public JdbcClientDetailsService clientDetailsSrv() {
return new JdbcClientDetailsService(oauthDataSource());
}
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(oauthDataSource());
}
#Bean
public ApprovalStore approvalStore() {
return new JdbcApprovalStore(oauthDataSource());
}
#Bean
public AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(oauthDataSource());
}
#Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
#Bean
#Primary
public AuthorizationServerTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore());
tokenServices.setTokenEnhancer(tokenEnhancer());
return tokenServices;
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsSrv());
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.authenticationManager(authenticationManager)
.approvalStore(approvalStore())
//.approvalStoreDisabled()
.authorizationCodeServices(authorizationCodeServices())
.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancer());
}
}
The main class
#SpringBootApplication
#EnableResourceServer
#EnableAuthorizationServer
#EnableConfigurationProperties
#EnableFeignClients("com.oauth2.proxies")
public class AuthorizationServerApplication {
public static void main(String[] args) {
SpringApplication.run(AuthorizationServerApplication.class, args);
}
}
The Web Security Configuration
#Configuration
#Order(1)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
#Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return new JdbcUserDetails();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception { // #formatter:off
http.requestMatchers()
.antMatchers("/",
"/login",
"/login.do",
"/registration",
"/registration/confirm/**",
"/registration/resendToken",
"/password/forgot",
"/password/change",
"/password/change/**",
"/oauth/authorize**")
.and()
.authorizeRequests()//autorise les requetes
.antMatchers(
"/",
"/login",
"/login.do",
"/registration",
"/registration/confirm/**",
"/registration/resendToken",
"/password/forgot",
"/password/change",
"/password/change/**")
.permitAll()
.and()
.requiresChannel()
.anyRequest()
.requiresSecure()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login.do")
.usernameParameter("username")
.passwordParameter("password")
.and()
.userDetailsService(userDetailsServiceBean());
} // #formatter:on
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsServiceBean()).passwordEncoder(passwordEncoder());
}
}
Client side the WebSecurityConfigurerAdapter
#EnableOAuth2Sso
#Configuration
public class UiSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers(
"/",
"/index.html",
"/login**",
"/logout**",
//resources
"/assets/**",
"/static/**",
"/*.ico",
"/*.js",
"/*.json").permitAll()
.anyRequest()
.authenticated()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class);
}
}
the oauth2 configuration properties
oauth2-server is the service name (load balancer) on kubernetes and also the server path that is why it appears twice.
security:
oauth2:
client:
clientId: **********
clientSecret: *******
accessTokenUri: https://oauth2-server/oauth2-server/oauth/token
userAuthorizationUri: https://oauth2.mydomain.com/oauth2-server/oauth/authorize
resource:
userInfoUri: https://oauth2-server/oauth2-server/me
Here an important detail, the value of userAuthorizationUri is the address to access the oauth2-server from the outside of the k8s cluster. The client-service send back that address into the response with a 302 http code if the user is not connected and tries to access to the /login path of the client-service. then the user is redirected to the /login path of the oauth2-server.
https://oauth2.mydomain.com target an Nginx Ingress controller that handle the redirection to the load balancer service.
Here is a solution to this problem. It's not a Spring issue at all but a bad configuration of the Nginx Ingress controller.
The authentication process is done in several stages :
1 - the user clic on a login button that target the /login path of the client-server
2 - the client-server, if the user is not authenticated yet, send a response to the
browser with a 302 http code to redirect the user to the oauth2-server, the value of
the redirection is composed with the value of the
security.oauth2.client.userAuthorizationUri property
and the redirection url that will be used by the browser to allow the client-server to get the Token once the user is authenticated.
That url look like this :
h*tps://oauth2.mydomain.com/oauth2-server/oauth/authorize?client_id=autorisation_code_client&redirect_uri=h*tps://www.mydomain.com/login&response_type=code&state=bSWtGx
3 - the user is redirected to the previous url
4 - the oauth2-server send a 302 http code to the browser with the login url of the
oauth2-server, h*tps://oauth2.mydomain.com/oauth2-server/login
5 - the user submit his credentials and the token is created if they are correct.
6 - the user is redirected to the same address as at the step two, and the oauth-server
add informations to the redirect_uri value
7 - the user is redirected to the client-server. The redirection part of the response look like this :
location: h*tps://www.mydomain.com/login?code=gnpZ0r&state=bSWtGx
8 - the client-server contact the oauth2-server and obtain the token from the code and the state that authenticates it. It doesn't matter if the instance of the oauth2
server is different than the one used by the user to authenticate himself. Here the
client-server use the value of security.oauth2.client.accessTokenUri to get the
token, this is the internal load balancing service address that targets the oauth2 server
pods, so it doesn't pass through any Ingress controller.
So at the steps 3 to 6 the user must communicate with the same instance of the oauth2-server throught the Ingress controller in front of the load balancer service.
Its is possible by configuring the Nginx Ingress controller with a few annotations :
"annotations": {
...
"nginx.ingress.kubernetes.io/affinity": "cookie",
"nginx.ingress.kubernetes.io/session-cookie-expires": "172800",
"nginx.ingress.kubernetes.io/session-cookie-max-age": "172800",
"nginx.ingress.kubernetes.io/session-cookie-name": "route"
}
That way we ensure that the user will be redirected to the same pods/instance of the oauth2-server during the authentication process as long he's identified with the same cookie.
The affinity session mecanism is a great way to scale the authentication server and also the client-server. Once the user is authenticated he will always use the same instance of the client and keep his session informations.
Thanks to Christian Altamirano Ayala for his help.
By default an in-memory TokenStore is used.
The default InMemoryTokenStore is perfectly fine for a single server
If you want multiple pods, you probably should go for JdbcTokenStore
The JdbcTokenStore is the JDBC version of the same thing, which stores token data in a relational database. Use the JDBC version if you can share a database between servers, either scaled up instances of the same server if there is only one, or the Authorization and Resources Servers if there are multiple components. To use the JdbcTokenStore you need "spring-jdbc" on the classpath.
Source Spring Security: OAuth 2 Developers Guide

OAuth2AccessToken not set in Oauth2ClientContext after login

I'm having some difficulties to get client token relay working with Spring Boot 2.0.0.M7 and Spring Cloud Finchley M5. Please find the example code on github: https://github.com/hansvanbeneden/oauth-example
I have configured the oauth2Login like this:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.and()
.csrf().disable();
}
}
and the client registration repo like this:
#Configuration
#EnableOAuth2Client
public class OAuth2LoginConfig {
#Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.myWebsiteClientRegistration());
}
private ClientRegistration myWebsiteClientRegistration() {
return ClientRegistration
.withRegistrationId("myauth")
...
.build();
}
#Bean
public OAuth2RestOperations restOperations(OAuth2ClientContext oauth2ClientContext) {
return new OAuth2RestTemplate(resource(), oauth2ClientContext);
}
private OAuth2ProtectedResourceDetails resource() {
ClientRegistration myauthClient = myWebsiteClientRegistration();
AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
resource.setScope(new ArrayList<>(myauthClient.getScopes()));
...
return resource;
}
}
I would expect that the oauth2Login somehow sets the OAuth2AccessToken in the Oauth2ClientContext for the OAuth2RestTemplate to use it. But apparently this is not the case, because a UserRedirectRequiredException is thrown when I use the OAuth2RestTemplate.
Is there some magic annotation that I'm missing?
Can someone please send me in the right direction?
Please feel free to correct me if i'm wrong, but basically this is how I understand the issue:
Spring Boot 2.0 dropped support for spring-security-oauth2, since it now has it's own OAuth support (documented here: https://docs.spring.io/spring-security/site/docs/5.0.0.BUILD-SNAPSHOT/reference/htmlsingle/#jc-oauth2login)
This means you can't use the new oauth2Login configuration and expect the Oauth2RestTemplate to be able to use the oauth tokens set by oauth2Login
The following project was setup to allow the use of spring-security-oauth2 features in Spring Boot 2.0: https://docs.spring.io/spring-security-oauth2-boot/docs/current-SNAPSHOT/reference/htmlsingle/
To solve my issue I added the spring-security-oauth2-autoconfigure dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</dependency>
I removed the oauth2Login and added the EnableOauth2Ssso from the WebSecurityConfig:
#Configuration
#EnableOAuth2Sso
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.csrf().disable();
}
}
Then my Oauth2RestTemplate was able to find the OAuthToken that was acquired by logging in.
#Bean
public RestOperations restOperations(OAuth2ProtectedResourceDetails resourceDetails,
OAuth2ClientContext clientContext) {
return new OAuth2RestTemplate(resourceDetails, clientContext);
}
I have committed this solution on the following branch: https://github.com/hansvanbeneden/oauth-example/tree/implementation-with-spring-security-oauth2-boot

Resources