title: Spring OAuth2 - User info in Client Credentials grant type
body: <p>I've been developing Spring Cloud (with Netflix OSS stack) microservices architecture for some time. As you would expect, I've separated authorization server as a stand alone microservice. My front end application uses "password" grant type for user login purposes. However, I'm using "client-credentials" grant type for the rest calls that I make from front-end service to other back-end services. Client-credentials grant type is being used among other back-end services as well. By doing so, I am not able to get who is the actual invoker (currently logged in user) of a request. Is there a way to inject authentication and authorization info of the principal to the token that is being issued in client-credentials grant? </p>
  
  <p>My Authorization Server Config class</p>
  
  <pre><code>@Configuration
  @EnableAuthorizationServer
  @Order(Ordered.HIGHEST_PRECEDENCE)
  public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
  
  @Autowired
  private AuthenticationManager authenticationManager;
  
  @Override
  public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
      oauthServer.tokenKeyAccess("permitAll()")
          .checkTokenAccess("isAuthenticated()");
  }
  
  @Override
  public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
      clients.inMemory()
          .withClient("testclient")
          .secret("{noop}testsecret")
          .authorizedGrantTypes("authorization_code","password","client_credentials")
          .scopes("ui")
          .autoApprove(true)
      // .accessTokenValiditySeconds(3600)
      .and()
          .withClient("backend-service")
          .secret("{noop}backendsecret")
          .authorizedGrantTypes("client_credentials","refresh_token")
          .scopes("server")
           .autoApprove(true)
  }
  @Override
  public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
      endpoints.authenticationManager(authenticationManager);
      endpoints.tokenEnhancer(tokenEnhancer());
      endpoints.tokenStore(tokenStore());
  }
  
  @Bean
  public TokenStore tokenStore() {
      //return new JdbcTokenStore(dataSource);
      return new InMemoryTokenStore();
  }
  @Bean
  @Primary
  public AuthorizationServerTokenServices tokenServices() {
      DefaultTokenServices tokenServices = new DefaultTokenServices();
      tokenServices.setTokenEnhancer(tokenEnhancer());
      tokenServices.setTokenStore(tokenStore());
      return tokenServices;
  }
  
  @Bean
  public TokenEnhancer tokenEnhancer() {
      return new CustomTokenEnhancer();
  }
  </code></pre>
  
  <p>Security Config Class</p>
  
  <pre><code>@Configuration
  @Order(1)
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
  @Override
  protected void configure(HttpSecurity http) throws Exception {
  
      http.csrf().disable()
              .requestMatchers()
                  .antMatchers("/login", "/oauth/authorize")
                  .and()
                  .authorizeRequests()
                  .antMatchers("/resources/**", "/src/main/webapp/**","/css/**","/images/**").permitAll()
              .and()
              .formLogin()
                  .loginPage("/login")
                  .permitAll()
              .and()
              .logout()
              .permitAll().and().httpBasic().disable();
  
  }
  
  @Override
  public void configure(WebSecurity web) throws Exception {
      web.ignoring().antMatchers("/static/**","/resources/**", "/src/main/webapp/**","/css/**","/images/**");
  }
  
  @Override
  @Bean
  public AuthenticationManager authenticationManagerBean() throws Exception {
      return super.authenticationManagerBean();
  }
  
  @Override
  protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
      auth.inMemoryAuthentication().withUser("admin").password("{noop}a1b2c3#").roles("User");
  }
  
  }
  </code></pre>
  
  <p>I've tried to implement a Token Enhancer class to propogate additional data in token. However, I don't think this is the correct and secure way for what I'm trying to achieve.</p>
  
  <pre><code>public class CustomTokenEnhancer implements TokenEnhancer {
  @Override
  public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {
      final Map&lt;String, Object&gt; additionalInfo = new HashMap&lt;&gt;();
  
      additionalInfo.put("customInfo", "testdata");
  
      ((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(additionalInfo);
  
      return oAuth2AccessToken;
      }
  }
  </code></pre>
  
  <p>Your assistance would be appreciated.</p>