title: Spring Security's authentication.getName returns null in controller
body: <p>This is my first project in Spring. I am trying to get the username of the logged in user but it returns <code>null</code>. I have also tried the <code>AuthenticationPrincipal</code> annotation and other ways as well, still it returns <code>null</code>.</p>
  
  <p><code>WebSecurityConfiguration</code> class:</p>
  
  <pre><code>@EnableWebSecurity
  public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter{
  
      @Autowired
      private UserDetailsService customUserDetailsService;
  
      @Bean
      @Override
      public AuthenticationManager authenticationManagerBean() throws Exception {
          return super.authenticationManagerBean ();
      }
  
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth
              .userDetailsService(customUserDetailsService)
              .passwordEncoder(encoder());
      }
  
      @Override
      protected void configure (HttpSecurity http) throws Exception {
  
          http
              .csrf().disable()
              .antMatcher("/**")
              .authorizeRequests()
                  .antMatchers("/login**").permitAll()
                  .anyRequest().authenticated();
      }
  
      public PasswordEncoder encoder() {
          return NoOpPasswordEncoder.getInstance();
      }
  }
  </code></pre>
  
  <p><code>AuthorizationServerConfiguration</code> class:</p>
  
  <pre><code>@Configuration
  @EnableAuthorizationServer
  public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
  
      @Autowired
      private AuthenticationManager authenticationManager;
  
      @Autowired
      private DataSource dataSource;
  
      @Autowired 
      private CustomUserDetailsService userDetailsService;
  
      @Override
      public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
          security.checkTokenAccess("isAuthenticated()");
      }
  
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  
          clients.jdbc(dataSource);
      }
  
      @Bean
      public PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  
          endpoints.authenticationManager(authenticationManager)
              .tokenStore(tokenStore())
              .userDetailsService(userDetailsService)
              .approvalStoreDisabled();
      }
  
      @Bean 
      public TokenStore tokenStore() {
          return new JdbcTokenStore(dataSource);
      }
  
  }
  </code></pre>
  
  <p><code>ResourceServerConfiguration</code> class:</p>
  
  <pre><code>@Configuration
  @EnableResourceServer
  public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{
  
      @Autowired
      TokenStore tokenStore;
  
      @Autowired
      DataSource dataSource;
  
      @Override
      public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
          resources.resourceId("scout").tokenStore(tokenStore);
      }
  
      @Override
      public void configure(HttpSecurity http) throws Exception {
  
          http
              .authorizeRequests()
                  .antMatchers("/oauth/token", "/oauth/authorize **").permitAll();
          http
              .requestMatchers()
                  .antMatchers("/api/patients/**")
                  .and()
              .authorizeRequests()
                  .antMatchers(HttpMethod.GET, "/api/patients/{\\d+}").access("hasAnyRole('PATIENT', 'DOCTOR')")
                  .antMatchers("/api/patients/{\\d+}/medical-records").access("hasAnyRole ('PATIENT', 'DOCTOR')")
                  .antMatchers("/api/patients/medical-records/{\\\\d+}/prescriptions").access("hasAnyRole('PATIENT', 'DOCTOR')")
                  .antMatchers("/api/patients/**").access("hasRole('PATIENT')") 
                  .and()
              .requestMatchers()
                  .antMatchers("/api/doctors/**")
                  .and()
              .authorizeRequests()
                  .antMatchers("/api/doctors/**").access("hasRole('DOCTOR')"); 
      }
  }
  </code></pre>
  
  <p>Below is the controller:</p>
  
  <pre><code>@GetMapping("/doctors")
  public Doctor getDoctor(Authentication user) {
      System.out.println(user.getName());
      return doctorService.getDoctor(user.getName());
  }
  </code></pre>
  
  <p>************************************Update********************************</p>
  
  <p>I am using oauth2 for security. I am trying to get the username of the logged in user in my controller above. I have tried to print the Principal object and I get 
  <code>org.springframework.security.oauth2.provider.OAuth2Authentication@24d14be1: Principal: com.prescribr.rest.service.CustomUserDetails@56d40b2f; Credentials: [PROTECTED]; Authenticated: true; Details: remoteAddress=0:0:0:0:0:0:0:1, sessionId=&lt;SESSION&gt;, tokenType=bearertokenValue=&lt;TOKEN&gt;; Granted Authorities: ROLE_DOCTOR</code></p>
  
  <p>On the other note, principal.getName() returns null.</p>
  
  <p>I am using the access token in my header while sending the request as below in postman.</p>
  
  <pre><code>authorization: bearer theToken
  </code></pre>
  
  <p>CustomUserDetails class:</p>
  
  <pre><code>public class CustomUserDetails extends Users implements UserDetails {
  
      private static final long serialVersionUID = -8170449272852748515L;
  
      public CustomUserDetails(final Users user) {
          super(user);
      }
  
      @Override
      public Collection&lt;? extends GrantedAuthority&gt; getAuthorities() {
  
          return getRoles()
                  .stream()
                  .map(role -&gt; new SimpleGrantedAuthority("ROLE_" + role.getRole()))
                  .collect(Collectors.toList());
      }
  
      @Override
      public String getPassword() {
          // TODO Auto-generated method stub
          return super.getPassword();
      }
  
      @Override
      public String getUsername() {
          // TODO Auto-generated method stub
          return super.getEmail();
      }
  
      @Override
      public boolean isAccountNonExpired() {
          // TODO Auto-generated method stub
          return true;
      }
  
      @Override
      public boolean isAccountNonLocked() {
          // TODO Auto-generated method stub
          return true;
      }
  
      @Override
      public boolean isCredentialsNonExpired() {
          // TODO Auto-generated method stub
          return true;
      }
  
      @Override
      public boolean isEnabled() {
          // TODO Auto-generated method stub
          return true;
      }
  
  }
  </code></pre>
  
  <p>CustomUserDetailsService class:</p>
  
  <pre><code>@Service
  public class CustomUserDetailsService implements UserDetailsService {
  
      @Autowired
      private UsersRepository userRepository;
  
      @Override
      public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
  
          Optional&lt;Users&gt; usersOptional = userRepository.findByEmail(email);
  
          Users user = null;
  
          if(usersOptional.isPresent()) {
              System.out.println(usersOptional.isPresent());
              user = usersOptional.get();
          }else {
              throw new RuntimeException("Email is not registered!");
          }
  
          return new CustomUserDetails(user);
      }
  
  }
  </code></pre>
  
  <p>Users class:</p>
  
  <pre><code>@Entity
  @Table(name="users")
  public class Users {
  
      @Id
      @GeneratedValue(strategy=GenerationType.IDENTITY)
      @Column(name="id")
      private int id; 
  
      @Column(name="first_name")
      private String firstName;
  
      @Column(name="last_name")
      private String lastName;
  
      @Column(name="email")
      private String email;
  
      @Column(name="password")
      private String password;
  
      @Column(name="active")
      private int active;
  
      @OneToMany(cascade=CascadeType.ALL, 
                 fetch=FetchType.EAGER
                 )
      @JoinColumn(name="user_id")
      private Set&lt;Role&gt; roles;
  
      public Users() {}
  
      public Users(Users user) {
          this.id = user.id;
          this.firstName = user.firstName;
          this.lastName = user.lastName;
          this.email = user.email;
          this.password = user.password;
          this.active = user.active;
          this.roles = user.roles;
      }
  
      public int getId() {
          return id;
      }
  
      public void setId(int id) {
          this.id = id;
      }
  
      public String getFirstName() {
          return firstName;
      }
  
      public void setFirstName(String firstName) {
          this.firstName = firstName;
      }
  
      public String getLastName() {
          return lastName;
      }
  
      public void setLastName(String lastName) {
          this.lastName = lastName;
      }
  
      public String getEmail() {
          return email;
      }
  
      public void setEmail(String email) {
          this.email = email;
      }
  
      public String getPassword() {
          return password;
      }
  
      public void setPassword(String password) {
          this.password = password;
      }
  
      public int getActive() {
          return active;
      }
  
      public void setActive(int active) {
          this.active = active;
      }
  
      public Set&lt;Role&gt; getRoles() {
          return roles;
      }
  
      public void setRoles(Set&lt;Role&gt; roles) {
          this.roles = roles;
      }
  
  }
  </code></pre>
  
  <p>Thanks again!</p>