title: Spring Security with OAuth2 losing session
body: <p>We have a Spring Boot-based Gateway using Spring Security, OAuth2 login, and Zuul routing. It is also using Spring Session to store sessions in Redis. This Gateway stores an OAuth2 token in the session and forwards the OAuth2 Bearer token to backend services.</p>
  <p>We have an issue where users are being signed out quite often. It appears this happens roughly hourly. We are not even quite sure what is causing this with all the different tools in place.</p>
  <p>Our session cookie in the browser expires in a longer period of time. So I suspect it is either Spring invalidating the session, or the OAuth2 token expiring.</p>
  <p>From a quick inspection of the code, it appears that <code>OAuth2TokenRelayFilter</code> supports refreshing the token. Is this correct?</p>
  <p>How can track down the cause of this and fix it?</p>
  <p>For reference, we are using these versions:</p>
  <ul>
  <li>Spring Boot 2.1.12</li>
  <li>Spring Cloud Greenwich.SR4</li>
  </ul>
  <p>Here are some relevant snippets.</p>
  <p>Our web security config for the web pages.</p>
  <pre><code>@Configuration
  @EnableWebSecurity
  @EnableOAuth2Sso
  @Order(SecurityProperties.BASIC_AUTH_ORDER - 2)
  @Profile(&quot;!security-disabled&quot;)
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter
  {
      @Override
      public void configure(HttpSecurity http) throws Exception {
          // @formatter:off
              http
                  .authorizeRequests()
                      .antMatchers(&quot;/login&quot;, &quot;/login/**&quot;, &quot;/favicon.ico&quot;).permitAll()
                      .antMatchers(&quot;/signout&quot;).authenticated()
                      .anyRequest().hasAnyRole(&quot;ADMIN&quot;, &quot;MEMBER&quot;)
                      .and()
                  .csrf()
                      .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                      .and()
                  .httpBasic()
                      .disable()
                  .formLogin()
                      .disable()
                  .logout()
                      .logoutUrl(&quot;/signout&quot;)
                      .deleteCookies(&quot;SESSION&quot;)
                      .and()
              // @formatter:on
      }
  </code></pre>
  <p>Security configuration for API paths.</p>
  <pre><code>@Configuration
  @Order(SecurityProperties.BASIC_AUTH_ORDER - 2 - 10)
  @Profile(&quot;!security-disabled&quot;)
  public class ApiSecurityConfig extends WebSecurityConfigurerAdapter
  {
      public void configure(HttpSecurity http) throws Exception {
          // @formatter:off
              http.requestMatchers()
                      .antMatchers(&quot;/api/**&quot;)
                      .and()
                      .authorizeRequests()
                      .antMatchers(&quot;/**&quot;).hasAnyRole(&quot;ADMIN&quot;, &quot;MEMBER&quot;)
                          .and()
                      .csrf()
                          .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                          .and()
                      .headers()
                          .frameOptions().sameOrigin()
                          .and()
                      .httpBasic()
                          .disable()
                      .formLogin()
                          .disable()
                      .logout()
                          .disable()
                      .exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint());
              // @formatter:on
      }
  
  }
  </code></pre>
  <p><strong>Update</strong></p>
  <p>We have done some debugging of the Spring internals. First, we found that we were missing an <code>OAuth2RestTemplate</code>. Per the <a href="https://docs.spring.io/spring-security-oauth2-boot/docs/current/reference/html5/#boot-features-security-custom-user-info-client" rel="nofollow noreferrer">OAuth2 Boot documentation</a> we found how to add it with:</p>
  <pre><code>@Bean
  public OAuth2RestTemplate oauth2RestTemplate(
          OAuth2ClientContext oauth2ClientContext,
          OAuth2ProtectedResourceDetails details)
  {
      return new OAuth2RestTemplate(details, oauth2ClientContext);
  }
  
  </code></pre>
  <p>This is now throwing an exception when <code>OAuth2TokenRelayFilter</code> calls <code>restTemplate.getAccessToken().getValue();</code>.</p>
  <blockquote>
  <p>A redirect is required to get the users approval</p>
  </blockquote>
  <p>This exception is thrown from <a href="https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java#L362-L363" rel="nofollow noreferrer">AuthorizationCodeAccessTokenProvider</a>.</p>