title: How do I take the response from Discord OAUTH2 and translate it in to my own UserDetails that I can use throughout my code
body: <p>I am using Spring Boot + Spring Security OAUTH 2 for my app. I want to use Spring OAUTH2 to &quot;Login with Discord&quot; and then parse the information that discord gives on an authentication success into my own JPA Entity which implements <code>UserDetails</code>. Also, I want to implement my own <code>UserDetailsService</code> to return that custom user entity that I created.</p>
  <p>Basically, I only want Discord to provide unique information about a user to I can construct my own <code>Account</code> entity based on the response.</p>
  <p>I've read the following articles but I still don't understand how to do it:</p>
  <p><a href="https://www.baeldung.com/spring-security-oauth-principal-authorities-extractor" rel="nofollow noreferrer">https://www.baeldung.com/spring-security-oauth-principal-authorities-extractor</a></p>
  <p><a href="https://www.devglan.com/spring-security/spring-oauth2-role-based-authorization" rel="nofollow noreferrer">https://www.devglan.com/spring-security/spring-oauth2-role-based-authorization</a></p>
  <p>Also, here is my OAuth2 Setup:</p>
  <p>Security Config (<code>WebSecurityConfigurerAdapter</code>):</p>
  <pre class="lang-java prettyprint-override"><code>@Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private AuthSuccessHandler authSuccessHandler;
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
              http
                      .authorizeRequests()
                      .antMatchers(HttpMethod.GET, &quot;/&quot;).permitAll()
                      .antMatchers(HttpMethod.GET, &quot;/favicon.ico&quot;).permitAll()
                      .antMatchers(HttpMethod.GET, &quot;/web/**&quot;).permitAll()
                      .antMatchers(HttpMethod.GET, &quot;/oauth2/authorization/discord&quot;).anonymous()
                      .antMatchers(HttpMethod.GET, &quot;/login&quot;).anonymous()
                      .antMatchers(HttpMethod.GET, &quot;/logout&quot;).permitAll()
                      .and()
                      .logout()
                      .logoutSuccessUrl(&quot;/&quot;)
                      .and()
                      .oauth2Login()
                      .successHandler(authSuccessHandler)
                      .tokenEndpoint().accessTokenResponseClient(accessTokenResponseClient())
                      .and()
                      .userInfoEndpoint().userService(userService());
      }
  
      @Bean
      public OAuth2AccessTokenResponseClient&lt;OAuth2AuthorizationCodeGrantRequest&gt; accessTokenResponseClient() {
          DefaultAuthorizationCodeTokenResponseClient client = new DefaultAuthorizationCodeTokenResponseClient();
  
          client.setRequestEntityConverter(new OAuth2AuthorizationCodeGrantRequestEntityConverter() {
              @Override
              public RequestEntity&lt;?&gt; convert(OAuth2AuthorizationCodeGrantRequest oauth2Request) {
                  return addUserAgentHeader(Objects.requireNonNull(super.convert(oauth2Request)));
              }
          });
  
          return client;
      }
  
      @Bean
      public OAuth2UserService&lt;OAuth2UserRequest, OAuth2User&gt; userService() {
          DefaultOAuth2UserService service = new DefaultOAuth2UserService();
  
          service.setRequestEntityConverter(new OAuth2UserRequestEntityConverter() {
              @Override
              public RequestEntity&lt;?&gt; convert(OAuth2UserRequest userRequest) {
                  return addUserAgentHeader(
                          Objects.requireNonNull(super.convert(userRequest)));
              }
          });
  
          return service;
      }
  
      private RequestEntity&lt;?&gt; addUserAgentHeader(RequestEntity&lt;?&gt; request) {
          HttpHeaders headers = new HttpHeaders();
          headers.putAll(request.getHeaders());
          headers.add(HttpHeaders.USER_AGENT, &quot;Mozilla/5.0 (X11; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0&quot;);
  
          return new RequestEntity&lt;&gt;(request.getBody(), headers, request.getMethod(), request.getUrl());
      }
  }
  </code></pre>
  <p>AuthSuccessHandler (<code>AuthenticationSuccessHandler</code>)
  As you can see for this I am trying to work around the problem by saving a JPA entity based on the information given by discord and only pulling from the database as opposed to getting the current user, which prevents me from using roles and authorities.</p>
  <pre class="lang-java prettyprint-override"><code>@Component
  @RequiredArgsConstructor
  @Slf4j
  public class AuthSuccessHandler implements AuthenticationSuccessHandler {
  
      private final AccountRepository accountRepository;
      private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
  
  
      @Override
      public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
          AuthenticationSuccessHandler.super.onAuthenticationSuccess(request, response, chain, authentication);
      }
  
      @Override
      public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException {
          OAuth2User oAuth2User = ((OAuth2AuthenticationToken) authentication).getPrincipal();
  //        oAuth2User.getAttributes().forEach((s, o) -&gt; {
  //            System.out.println(s + &quot; : &quot; + o);
  //        });
  
          Long discordId = Long.parseLong(Objects.requireNonNull(oAuth2User.getAttribute(&quot;id&quot;)));
          Optional&lt;Account&gt; accountOptional = accountRepository.findAccountByDiscordId(discordId);
          if (!httpServletResponse.isCommitted()) {
              if (accountOptional.isEmpty()) {
                  accountRepository.save(getAccountFromOAuth2User(oAuth2User));
              }
              redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, &quot;/dashboard&quot;);
          } else {
              log.warn(&quot;Response committed&quot;);
          }
  
      }
  
      private Account getAccountFromOAuth2User(OAuth2User oAuth2User) {
          return new Account(Long.parseLong(oAuth2User.getAttribute(&quot;id&quot;)),oAuth2User.getAttribute(&quot;username&quot;), oAuth2User.getAttribute(&quot;discriminator&quot;));
      }
  
  }
  </code></pre>
  <p>application.properties</p>
  <pre><code>spring.security.oauth2.client.registration.discord.client-name=Discord
  spring.security.oauth2.client.registration.discord.client-id=**CLIENT**
  spring.security.oauth2.client.registration.discord.client-secret=**SECRET**
  spring.security.oauth2.client.registration.discord.clientAuthenticationMethod=post
  spring.security.oauth2.client.registration.discord.authorizationGrantType=authorization_code
  spring.security.oauth2.client.registration.discord.redirect-uri=http://localhost:8081/login/oauth2/code/discord
  spring.security.oauth2.client.registration.discord.scope=identify
  
  spring.security.oauth2.client.provider.discord.authorization-uri=https://discordapp.com/api/oauth2/authorize
  spring.security.oauth2.client.provider.discord.token-uri=https://discordapp.com/api/oauth2/token
  spring.security.oauth2.client.provider.discord.user-info-uri=https://discordapp.com/api/users/@me
  spring.security.oauth2.client.provider.discord.user-name-attribute=username
  </code></pre>
  <p>Any help on this would be appreciated.</p>
  <p>Thanks in advance!</p>
  <p>EDIT:
  Most of the code used is from this GitHub repository:</p>
  <p><a href="https://github.com/Samurus/spring-boot-discord-oauth-example" rel="nofollow noreferrer">https://github.com/Samurus/spring-boot-discord-oauth-example</a></p>