title: Authentication Principal is empty while using Spring Session Redis
body: <p>I am building rest API using Spring Boot v1.3.3. API is secured by Spring Security. I have implemented custom user details service to have custom principal in authentication context.</p>
  
  <p>I needed to share sessions of API with other Spring app so I choosen to implement Spring Session with Redis server in my app using this tutorial <em>docs.spring.io/spring-session/docs/current/reference/html5/guides/security.html</em>. Unfortunetly it caused Authentication Principal to stop working. When I am trying to get current Principal either by annotation <code>@AuthenticationPrincipal CustomUserDetails user</code> or by <code>SecurityContextHolder.getContext().getAuthentication().getPrincipal()</code> it returns my custom user details but with <code>Id = 0</code> and all fields set to <code>null</code>
  (<a href="http://i.stack.imgur.com/Ytjym.png" rel="nofollow">screen from debugging</a>). I can't even get username from <code>SecurityContextHolder.getContext().getAuthentication().getName()</code>.</p>
  
  <p>After I commented Redis code and maven dependency it works (<a href="http://i.stack.imgur.com/FUWhV.png" rel="nofollow">see debug screen</a>). How to make it working with Spring Session and Redis server?</p>
  
  <p>Here is some code from the app:</p>
  
  <p><em>Some example method to check Principal</em></p>
  
  <pre><code>@RequestMapping(value = "/status", method = RequestMethod.GET)
  public StatusData status(@AuthenticationPrincipal CustomUserDetails user) {
      User user2 = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
      if (user != null) {
          String name = user.getUsername();
          return new StatusData(name);
      } else return new StatusData(null);
  }
  </code></pre>
  
  <p><em>Application and Redis config:</em></p>
  
  <pre><code>@Configuration
  @EnableRedisHttpSession
  public class AppConfig {
  
      @Bean
      public JedisConnectionFactory connectionFactory() {
          return new JedisConnectionFactory();
      }
  
      @Bean
      public CookieSerializer cookieSerializer() {
          DefaultCookieSerializer serializer = new DefaultCookieSerializer();
          serializer.setCookieName("JSESSIONID");
          serializer.setCookiePath("/");
          serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
          return serializer;
      }
  
      @Bean
      public ShaPasswordEncoder shaEncoder() {
          return new ShaPasswordEncoder(256);
      }
  
      @Bean
      public BCryptPasswordEncoder bCryptPasswordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Bean(name = "messageSource")
      public ResourceBundleMessageSource messageSource() {
          ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
          resourceBundleMessageSource.setBasename("messages/messages");
          return resourceBundleMessageSource;
      }
  
      @Bean
      public Validator basicValidator() {
          LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
          validator.setValidationMessageSource(messageSource());
          return validator;
      }
  
      public AppConfig() {
          DateTimeZone.setDefault(DateTimeZone.UTC);
      }
  }
  </code></pre>
  
  <p><em>Initializer (used for Redis Session)</em></p>
  
  <pre><code>public class Initializer extends AbstractHttpSessionApplicationInitializer {
  
  }
  </code></pre>
  
  <p><em>SecurityInitializer (used for Redis session)</em></p>
  
  <pre><code>public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
  
      public SecurityInitializer() {
          super(WebSecurityConfig.class, AppConfig.class);
      }
  }
  </code></pre>
  
  <p><em>WebSecurityConfig (Spring Security config)</em></p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  //@EnableWebMvcSecurity
  @ComponentScan(basePackageClasses = {UserRepository.class, CustomUserDetailsService.class})
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private DataSource dataSource;
  
      @Autowired
      private UserDetailsService customUserDetailsService;
  
      @Autowired
      private HttpAuthenticationEntryPoint httpAuthenticationEntryPoint;
  
      @Autowired
      private AuthSuccessHandler authSuccessHandler;
  
      @Autowired
      private AuthFailureHandler authFailureHandler;
  
      @Autowired
      private HttpLogoutSuccessHandler logoutSuccessHandler;
  
      @Autowired
      private BCryptPasswordEncoder bCryptPasswordEncoder;
  
      /**
       * Persistent token repository stored in database. Used for remember me feature.
       */
      @Bean
      public PersistentTokenRepository tokenRepository() {
          JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
          db.setDataSource(dataSource);
          return db;
      }
  
      /**
       * Enable always remember feature.
       */
      @Bean
      public AbstractRememberMeServices rememberMeServices() {
          CustomTokenPersistentRememberMeServices rememberMeServices = new CustomTokenPersistentRememberMeServices("xxx", customUserDetailsService, tokenRepository());
          rememberMeServices.setAlwaysRemember(true);
          rememberMeServices.setTokenValiditySeconds(1209600);
          return rememberMeServices;
      }
  
      /**
       * Configure spring security to use in REST API.
       * Set handlers to immediately return HTTP status codes.
       * Enable remember me tokens.
       */
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
                  .csrf().disable()
                  .exceptionHandling()
                  .authenticationEntryPoint(httpAuthenticationEntryPoint)
                  .and()
                  .authorizeRequests()
                  .antMatchers("/cookie", "/register", "/redirect/**", "/track/**")
                  .permitAll()
                  .anyRequest().authenticated()
                  .and()
                  .formLogin()
                  .loginPage("/login")
                  .permitAll()
                  .successHandler(authSuccessHandler)
                  .failureHandler(authFailureHandler)
                  .and()
                  .logout()
                  .permitAll().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler)
                  .and()
                  .rememberMe().rememberMeServices(rememberMeServices())
                  .and()
                  .headers()
                  .addHeaderWriter(new HeaderWriter() {
                      /**
                       * Header to allow access from javascript AJAX in chrome extension.
                       */
                      @Override
                      public void writeHeaders(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
                          String corsUrl = "https://mail.google.com";
                          if (httpServletRequest.getHeader("Origin") != null &amp;&amp; httpServletRequest.getHeader("Origin").equals(corsUrl)) {
                              httpServletResponse.setHeader("Access-Control-Allow-Origin", "https://mail.google.com");
                              httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
                              httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
                              httpServletResponse.setHeader("Access-Control-Expose-Headers", "Location");
                          }
                      }
                  });
      }
  
      /**
       * Set custom user details service to allow for store custom user details and set password encoder to BCrypt.
       */
      @Autowired
      public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth
                  .userDetailsService(customUserDetailsService).passwordEncoder(bCryptPasswordEncoder);
      }
  }
  </code></pre>
  
  <p><em>Maven dependencies</em></p>
  
  <pre><code>&lt;dependencies&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;${project.groupId}&lt;/groupId&gt;
          &lt;artifactId&gt;models&lt;/artifactId&gt;
          &lt;version&gt;${project.version}&lt;/version&gt;
      &lt;/dependency&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-data-jpa&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.hibernate&lt;/groupId&gt;
          &lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;
          &lt;version&gt;5.2.3.Final&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;joda-time&lt;/groupId&gt;
          &lt;artifactId&gt;joda-time&lt;/artifactId&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.jadira.usertype&lt;/groupId&gt;
          &lt;artifactId&gt;usertype.core&lt;/artifactId&gt;
          &lt;version&gt;3.1.0.CR1&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.fasterxml.jackson.jaxrs&lt;/groupId&gt;
          &lt;artifactId&gt;jackson-jaxrs-json-provider&lt;/artifactId&gt;
          &lt;version&gt;2.2.1&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.fasterxml.jackson.datatype&lt;/groupId&gt;
          &lt;artifactId&gt;jackson-datatype-joda&lt;/artifactId&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.maxmind.geoip2&lt;/groupId&gt;
          &lt;artifactId&gt;geoip2&lt;/artifactId&gt;
          &lt;version&gt;2.6.0&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.ganyo&lt;/groupId&gt;
          &lt;artifactId&gt;gcm-server&lt;/artifactId&gt;
          &lt;version&gt;1.0.2&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.session&lt;/groupId&gt;
          &lt;artifactId&gt;spring-session&lt;/artifactId&gt;
          &lt;version&gt;1.1.1.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-redis&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;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-test&lt;/artifactId&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
          &lt;artifactId&gt;spring-security-test&lt;/artifactId&gt;
          &lt;version&gt;4.0.4.RELEASE&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.jayway.jsonpath&lt;/groupId&gt;
          &lt;artifactId&gt;json-path&lt;/artifactId&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
  &lt;/dependencies&gt;
  </code></pre>