title: Java SpringBoot Rest OAuth2 Principal is null
body: <p>I tried different tutorials on <strong>Java SpringBoot REST OAuth2</strong>  authentication. I tried to and combine them with simple web form authentication, but still i am not able to get Principal class object. I got <code>null</code> every time on my Rest Controller (showed in lines bellow), am I missing something?</p>
  
  <p><strong>AuthorizationServerConfiguration.java</strong></p>
  
  <pre><code>import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
  import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
  import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
  import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
  import org.springframework.security.oauth2.provider.token.TokenStore;
  
  @Configuration
  @EnableAuthorizationServer
  public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
  
      private static final String REALM = "MY_OAUTH_REALM";
  
      @Autowired
      private TokenStore tokenStore;
  
      @Autowired
      private AuthenticationManager authenticationManager;
  
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
          clients.inMemory()
                  .withClient("my-trusted-client")
                  .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                  .scopes("read", "write", "trust")
                  .secret("secret")
                  .accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.
                  refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.
      }
  
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
          endpoints.tokenStore(tokenStore).authenticationManager(authenticationManager);
      }
  
  }
  </code></pre>
  
  <p><strong>ResourceServerConfiguration.java</strong></p>
  
  <pre><code>import org.springframework.context.annotation.Configuration;
  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
  import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
  import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
  import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
  
  @Configuration
  @EnableResourceServer
  public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
  
      private static final String RESOURCE_ID = "rest_api";
  
      @Override
      public void configure(ResourceServerSecurityConfigurer resources) {
          resources.resourceId(RESOURCE_ID).stateless(false);
      }
  
      @Override
      public void configure(HttpSecurity http) throws Exception {
          http.anonymous().disable()
              .authorizeRequests()
              .antMatchers("/api/**").authenticated()
              .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
      }
  
  }
  </code></pre>
  
  <p><strong>OAuth2SecurityConfiguration.java</strong></p>
  
  <pre><code>import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.web.servlet.FilterRegistrationBean;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  import org.springframework.security.core.userdetails.UserDetailsService;
  import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  import org.springframework.security.oauth2.provider.token.TokenStore;
  import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
  import org.springframework.web.cors.CorsConfiguration;
  import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  import org.springframework.web.filter.CorsFilter;
  
  import javax.annotation.Resource;
  
  @Configuration
  @EnableWebSecurity
  public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
  
      @Resource(name = "userService")
      private UserDetailsService userDetailsService;
  
      @Override
      @Bean
      public AuthenticationManager authenticationManagerBean() throws Exception {
          return super.authenticationManagerBean();
      }
  
      @Autowired
      public void globalUserDetails(AuthenticationManagerBuilder auth)throws Exception {
              auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
      http.csrf().disable()
              .anonymous().disable()
              .authorizeRequests()
              .antMatchers("/login").permitAll();
      }
  
      @Bean
      public TokenStore tokenStore() {
          return new InMemoryTokenStore();
      }
  
      @Bean
      public BCryptPasswordEncoder bCryptPasswordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Bean
      public FilterRegistrationBean corsFilter() {
          UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
          CorsConfiguration config = new CorsConfiguration();
          config.setAllowCredentials(true);
          config.addAllowedOrigin("*");
          config.addAllowedHeader("*");
          config.addAllowedMethod("*");
          source.registerCorsConfiguration("/**", config);
          FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
          bean.setOrder(0);
          return bean;
      }
  
  }
  </code></pre>
  
  <p><strong>UserServiceImpl.java</strong></p>
  
  <pre><code>import cz.uhk.ppro.semestralniprojekt.model.user.User;
  import cz.uhk.ppro.semestralniprojekt.model.user.UserRepository;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
  import org.springframework.security.core.userdetails.UserDetails;
  import org.springframework.security.core.userdetails.UserDetailsService;
  import org.springframework.security.core.userdetails.UsernameNotFoundException;
  import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  import org.springframework.stereotype.Service;
  
  import java.util.Arrays;
  import java.util.List;
  
  @Service(value = "userService")
  public class UserServiceImpl implements UserDetailsService, UserService {
  
      @Autowired
      private UserRepository userRepository;
  
      @Autowired
      private BCryptPasswordEncoder bCryptPasswordEncoder;
  
      @Override
      public void save(User user) {
          user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
          userRepository.save(user);
      }
  
      @Override
      public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
          User user = findByUsername(s);
          if(user == null){
              throw new UsernameNotFoundException("Invalid username or password.");
          }
  
          return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthority());
      }
  
      @Override
      public User findByUsername(String username) {
          return userRepository.findByUsername(username);
      }
  
      private List getAuthority() {
          return Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN"));
      }
  
  }
  </code></pre>
  
  <p><strong>ApiController.java</strong></p>
  
  <pre><code>@RestController
  @RequestMapping("/api")
  public class ApiController {
      @RequestMapping("/monthFinanceOverview")
      public MonthFinanceOverview monthFinanceOverview(
              @RequestParam(value = "month", required = false) String month,
              Principal principal
      ) {
          DateTimeFormatter monthDateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
          User user = users.findByUsername(principal.getName());
          //Here i got error every time
      }
  }
  </code></pre>
  
  <p><strong>pom.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;groupId&gt;cz.uhk.ppro&lt;/groupId&gt;
      &lt;artifactId&gt;semestralni-projekt&lt;/artifactId&gt;
      &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
  
      &lt;name&gt;semestralni-projekt&lt;/name&gt;
      &lt;description&gt;Semestrální projekt Java EE, Spring&lt;/description&gt;
  
      &lt;parent&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
          &lt;version&gt;1.5.8.RELEASE&lt;/version&gt;
          &lt;relativePath/&gt;
      &lt;/parent&gt;
  
      &lt;properties&gt;
          &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
          &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
          &lt;java.version&gt;1.8&lt;/java.version&gt;
      &lt;/properties&gt;
  
      &lt;dependencies&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.thymeleaf.extras&lt;/groupId&gt;
              &lt;artifactId&gt;thymeleaf-extras-springsecurity4&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
              &lt;scope&gt;runtime&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;mysql&lt;/groupId&gt;
              &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.security.oauth&lt;/groupId&gt;
              &lt;artifactId&gt;spring-security-oauth2&lt;/artifactId&gt;
              &lt;version&gt;2.3.0.RELEASE&lt;/version&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.jetbrains&lt;/groupId&gt;
              &lt;artifactId&gt;annotations&lt;/artifactId&gt;
              &lt;version&gt;13.0&lt;/version&gt;
          &lt;/dependency&gt;
      &lt;/dependencies&gt;
  
      &lt;build&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                  &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
      &lt;/build&gt;
  
  
  &lt;/project&gt;
  </code></pre>