title: Spring Boot oauth2 with local user database
body: <p>I have implemented OIDC authentication in my Spring Boot web application by adding the <code>spring-boot-starter-oauth2-client</code> dependency and configuring OAuth2 client settings in <code>application.properties</code>.</p>
  <p>In the <a href="https://spring.io/guides/tutorials/spring-boot-oauth2/" rel="nofollow noreferrer">Spring Boot and OAuth2</a> guide there is a section &quot;How to Add a Local User Database&quot;:</p>
  <blockquote>
  <p>How to Add a Local User Database</p>
  <p>Many applications need to hold data
  about their users locally, even if authentication is delegated to an
  external provider. We don’t show the code here, but it is easy to do
  in two steps.</p>
  <ol>
  <li><p>Choose a backend for your database, and set up some repositories
  (using Spring Data, say) for a custom User object that suits your
  needs and can be populated, fully or partially, from external
  authentication.</p>
  </li>
  <li><p>Implement and expose OAuth2UserService to call the Authorization
  Server as well as your database. Your implementation can delegate to
  the default implementation, which will do the heavy lifting of calling
  the Authorization Server. Your implementation should return something
  that extends your custom User object and implements OAuth2User.</p>
  </li>
  </ol>
  <p>Hint: add a field in the User object to link to a unique identifier in
  the external provider (not the user’s name, but something that’s
  unique to the account in the external provider).</p>
  </blockquote>
  <p>I have searched a bit but I have not found a code example for the scenario described in the excerpt.</p>
  <p>What is the best way to implement the scenario above?</p>
  <p>I guess the main parts would be:</p>
  <ul>
  <li>On OIDC login, automatically create a user in the database if it does not exist</li>
  <li>The web application controller methods have access to the database object that represents the  logged-in user</li>
  </ul>
  <p><em>Update:</em></p>
  <p>The guide has <a href="https://github.com/spring-guides/tut-spring-boot-oauth2/issues/41#issuecomment-253157521" rel="nofollow noreferrer">a github issue comment</a> that suggests to look at the  <code>custom-error</code> sample from the guide's <a href="https://github.com/spring-guides/tut-spring-boot-oauth2/blob/c6f47f0f952732f2379a87a7dd7f0917dd6c51a1/custom-error/src/main/java/com/example/SocialApplication.java#L62" rel="nofollow noreferrer">source code</a>. I guess the first part (on OIDC login, automatically create a user if one does not exist) can be done after the call to <code>DefaultOAuth2UserService().loadUser(request)</code>. But what about the second part - how can my custom db-backed-user-object be made available to my web application's controller methods?</p>
  <pre><code>@Bean
  public OAuth2UserService&lt;OAuth2UserRequest, OAuth2User&gt; oauth2UserService(WebClient rest) {
      DefaultOAuth2UserService delegate = new DefaultOAuth2UserService();
      return request -&gt; {
          OAuth2User user = delegate.loadUser(request);
          if (!&quot;github&quot;.equals(request.getClientRegistration().getRegistrationId())) {
              return user;
          }
  
          OAuth2AuthorizedClient client = new OAuth2AuthorizedClient
                  (request.getClientRegistration(), user.getName(), request.getAccessToken());
          String url = user.getAttribute(&quot;organizations_url&quot;);
          List&lt;Map&lt;String, Object&gt;&gt; orgs = rest
                  .get().uri(url)
                  .attributes(oauth2AuthorizedClient(client))
                  .retrieve()
                  .bodyToMono(List.class)
                  .block();
  
          if (orgs.stream().anyMatch(org -&gt; &quot;spring-projects&quot;.equals(org.get(&quot;login&quot;)))) {
              return user;
          }
  
          throw new OAuth2AuthenticationException(new OAuth2Error(&quot;invalid_token&quot;, &quot;Not in Spring Team&quot;, &quot;&quot;));
      };
  }
  </code></pre>