title: Spring social and security integration (vs anonymouse user)
body: <p>I tried to integrate spring security and spring social. The problem is when I try to create account for him in my system. I would like to avoid creating user with id "anonymousUser".</p>
  
  <p>For expected behaviour when I analyzed code from spring-social-security I expected to call method JdbcUsersConnectionRepository.findUserIdsWithConnection(Connection connection) for creating user and entry in the system. But when I run my code I find out this is not true. Before this action is calling implementation of SocialConfigurer.getUserId(). Great... If we have anonymous user it will be cached... But anyway getUserId is called before anything so authorization doesn't work. So I wrote my own implementation to this thing:</p>
  
  <pre><code>@Configuration
  @EnableSocial
  public class SocialConfig implements SocialConfigurer {
      @Autowired
      private DataSource dataSource;
      @Autowired
      private CustomerService customerService;
      @Autowired
      private CustomerProviderRepository customerProviderRepository;
      @Autowired
      private PasswordEncoder passwordEncoder;
  
  
      @Override
      public void addConnectionFactories(ConnectionFactoryConfigurer connectionFactoryConfigurer, Environment environment) {
      }
  
      @Override
      public UserIdSource getUserIdSource() {
          return () -&gt; {
              Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
              if (authentication == null || authentication.getName().equals("anonymousUser")) {
                  throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
              }
              return authentication.getName();
          };
      }
  
      @Override
      public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
          JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
          repository.setConnectionSignUp(new SocialConnectionSignUpService(customerService, customerProviderRepository, passwordEncoder));
          return repository;
      }
  }
  </code></pre>
  
  <p>Implementation of SocialCOnnectionSignUpService</p>
  
  <pre><code>public class SocialConnectionSignUpService implements ConnectionSignUp {
      private final CustomerService customerService;
      private final CustomerProviderRepository customerProviderRepository;
      private final PasswordEncoder passwordEncoder;
  
      public SocialConnectionSignUpService(CustomerService customerService, CustomerProviderRepository customerProviderRepository, PasswordEncoder passwordEncoder) {
          this.customerService = customerService;
          this.passwordEncoder = passwordEncoder;
          this.customerProviderRepository = customerProviderRepository;
      }
  
      @Override
      public String execute(Connection&lt;?&gt; connection) {
          ConnectionKey connectionKey = connection.getKey();
          UserProfile profile = connection.fetchUserProfile();
  
          Customer customer = customerService.findBy(profile.getEmail());
          if(customer == null) {
              customer = new Customer();
              customer.setEmail(profile.getEmail());
              customerService.add(customer);
          }
  
          SocialKey key = new SocialKey();
          key.setUserId(customer.getId().toString());
          key.setProviderUserId(connectionKey.getProviderUserId());
          key.setProviderId(connectionKey.getProviderId());
  
  
          CustomerProvider customerProvider = new CustomerProvider();
          customerProvider.setKey(key);
          customerProvider.setDisplayName(profile.getName());
          customerProviderRepository.save(customerProvider);
  
          return customerProvider.id();
      }
  }
  </code></pre>
  
  <p>And configuration of spring security:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class SecurityContext extends WebSecurityConfigurerAdapter {
      @Autowired
      private DataSource dataSource;
      @Autowired
      private CustomerRepository customerRepository;
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
                  .formLogin()
                      .loginPage("/login")
                      .loginProcessingUrl("/login/authenticate")
                      .permitAll()
                  .and()
                      .rememberMe()
                  .and()
                      .authorizeRequests()
                          .antMatchers("/signup/social").authenticated()
                          .antMatchers("/**").permitAll()
                  .and()
                      .apply(new SpringSocialConfigurer().postLoginUrl("/signup/social").alwaysUsePostLoginUrl(true))
                  .and()
                      .csrf().disable();
  
      }
  
      @Bean
      public SocialUserDetailsService socialUserDetailsService() {
          return new SocialUserDetailsServiceImpl(customerRepository);
      }
  
  }
  </code></pre>
  
  <p>Do you have any workaround or solution how to pass the problem?</p>