2016-06-24 4 views
1

私はFacebookのログインの統合にいくつかの問題があります。店舗SocialUserConnectionためOAuth2コールバック(null)を処理中に例外が発生しました。春の社会のFacebookのログイン

@Configuration 
@EnableSocial 
public class SocialConfig implements SocialConfigurer { 

    private final Logger log = LoggerFactory.getLogger(SocialConfig.class); 

    @Inject 
    Environment environment; 

    @Inject 
    ConnectionRepository customSocialConnectionRepository; 

    @Inject 
    SocialUserConnectionRepository socialUserConnectionRepository; 

    @Bean 
    public ConnectController connectController(ConnectionFactoryLocator connectionFactoryLocator) { 
     ConnectController controller = new ConnectController(connectionFactoryLocator, customSocialConnectionRepository); 
     controller.addInterceptor(new FacebookCustomConnectInterceptor()); 
     return controller; 
    } 

    @Override 
    public void addConnectionFactories(ConnectionFactoryConfigurer connectionFactoryConfigurer, Environment environment) { 
     // Facebook configuration 
     String facebookClientId = environment.getProperty("spring.social.facebook.clientId"); 
     String facebookClientSecret = environment.getProperty("spring.social.facebook.clientSecret"); 
     if (facebookClientId != null && facebookClientSecret != null) { 
      log.debug("Configuration FacebookConnectionFactory"); 
      connectionFactoryConfigurer.addConnectionFactory(
        new FacebookConnectionFactory(
          facebookClientId, 
          facebookClientSecret 
        ) 
      ); 
     } else { 
      log.error("Cannot configure FacebookConnectionFactory id or secret null"); 
     } 
    } 

    @Override 
    public UserIdSource getUserIdSource() { 
     return new AuthenticationNameUserIdSource(); 
    } 

    @Override 
    public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) { 
     return new CustomSocialUsersConnectionRepository(socialUserConnectionRepository, connectionFactoryLocator); 
    } 
} 

私が持っているドメインオブジェクト: は、ここに私の社会的な設定です。

私は、アプリケーションにユーザーを、Facebookの接続を処理登録し、ログインするConnectControllerを使用ConnectionRepository

public class CustomSocialConnectionRepository implements ConnectionRepository { 

    private String userId; 

    private SocialUserConnectionRepository socialUserConnectionRepository; 

    private ConnectionFactoryLocator connectionFactoryLocator; 

    public CustomSocialConnectionRepository(String userId, SocialUserConnectionRepository socialUserConnectionRepository, ConnectionFactoryLocator connectionFactoryLocator) { 
     this.userId = userId; 
     this.socialUserConnectionRepository = socialUserConnectionRepository; 
     this.connectionFactoryLocator = connectionFactoryLocator; 
    } 

    @Override 
    public MultiValueMap<String, Connection<?>> findAllConnections() { 
     List<SocialUserConnection> socialUserConnections = socialUserConnectionRepository.findAllByUserIdOrderByProviderIdAscRankAsc(userId); 
     List<Connection<?>> connections = socialUserConnectionsToConnections(socialUserConnections); 
     MultiValueMap<String, Connection<?>> connectionsByProviderId = new LinkedMultiValueMap<>(); 
     Set<String> registeredProviderIds = connectionFactoryLocator.registeredProviderIds(); 
     for (String registeredProviderId : registeredProviderIds) { 
      connectionsByProviderId.put(registeredProviderId, Collections.emptyList()); 
     } 
     for (Connection<?> connection : connections) { 
      String providerId = connection.getKey().getProviderId(); 
      if (connectionsByProviderId.get(providerId).size() == 0) { 
       connectionsByProviderId.put(providerId, new LinkedList<>()); 
      } 
      connectionsByProviderId.add(providerId, connection); 
     } 
     return connectionsByProviderId; 
    } 

    @Override 
    public List<Connection<?>> findConnections(String providerId) { 
     List<SocialUserConnection> socialUserConnections = socialUserConnectionRepository.findAllByUserIdAndProviderIdOrderByRankAsc(userId, providerId); 
     return socialUserConnectionsToConnections(socialUserConnections); 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public <A> List<Connection<A>> findConnections(Class<A> apiType) { 
     List<?> connections = findConnections(getProviderId(apiType)); 
     return (List<Connection<A>>) connections; 
    } 

    @Override 
    public MultiValueMap<String, Connection<?>> findConnectionsToUsers(MultiValueMap<String, String> providerUserIdsByProviderId) { 
     if (providerUserIdsByProviderId == null || providerUserIdsByProviderId.isEmpty()) { 
      throw new IllegalArgumentException("Unable to execute find: no providerUsers provided"); 
     } 

     MultiValueMap<String, Connection<?>> connectionsForUsers = new LinkedMultiValueMap<>(); 
     for (Map.Entry<String, List<String>> entry : providerUserIdsByProviderId.entrySet()) { 
      String providerId = entry.getKey(); 
      List<String> providerUserIds = entry.getValue(); 
      List<Connection<?>> connections = providerUserIdsToConnections(providerId, providerUserIds); 
      connections.forEach(connection -> connectionsForUsers.add(providerId, connection)); 
     } 
     return connectionsForUsers; 
    } 

    @Override 
    public Connection<?> getConnection(ConnectionKey connectionKey) { 
     SocialUserConnection socialUserConnection = socialUserConnectionRepository.findOneByUserIdAndProviderIdAndProviderUserId(userId, connectionKey.getProviderId(), connectionKey.getProviderUserId()); 
     return Optional.ofNullable(socialUserConnection) 
      .map(this::socialUserConnectionToConnection) 
      .orElseThrow(() -> new NoSuchConnectionException(connectionKey)); 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public <A> Connection<A> getConnection(Class<A> apiType, String providerUserId) { 
     String providerId = getProviderId(apiType); 
     return (Connection<A>) getConnection(new ConnectionKey(providerId, providerUserId)); 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public <A> Connection<A> getPrimaryConnection(Class<A> apiType) { 
     String providerId = getProviderId(apiType); 
     Connection<A> connection = (Connection<A>) findPrimaryConnection(providerId); 
     if (connection == null) { 
      throw new NotConnectedException(providerId); 
     } 
     return connection; 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public <A> Connection<A> findPrimaryConnection(Class<A> apiType) { 
     String providerId = getProviderId(apiType); 
     return (Connection<A>) findPrimaryConnection(providerId); 
    } 

    @Override 
    @Transactional 
    public void addConnection(Connection<?> connection) { 
     Long rank = getNewMaxRank(connection.getKey().getProviderId()).longValue(); 
     SocialUserConnection socialUserConnectionToSave = connectionToUserSocialConnection(connection, rank); 
     socialUserConnectionRepository.save(socialUserConnectionToSave); 
    } 

    @Override 
    @Transactional 
    public void updateConnection(Connection<?> connection) { 
     SocialUserConnection socialUserConnection = socialUserConnectionRepository.findOneByUserIdAndProviderIdAndProviderUserId(userId, connection.getKey().getProviderId(), connection.getKey().getProviderUserId()); 
     if (socialUserConnection != null) { 
      SocialUserConnection socialUserConnectionToUdpate = connectionToUserSocialConnection(connection, socialUserConnection.getRank()); 
      socialUserConnectionToUdpate.setId(socialUserConnection.getId()); 
      socialUserConnectionRepository.save(socialUserConnectionToUdpate); 
     } 
    } 

    @Override 
    @Transactional 
    public void removeConnections(String providerId) { 
     socialUserConnectionRepository.deleteByUserIdAndProviderId(userId, providerId); 
    } 

    @Override 
    @Transactional 
    public void removeConnection(ConnectionKey connectionKey) { 
     socialUserConnectionRepository.deleteByUserIdAndProviderIdAndProviderUserId(userId, connectionKey.getProviderId(), connectionKey.getProviderUserId()); 
    } 

    private Double getNewMaxRank(String providerId) { 
     List<SocialUserConnection> socialUserConnections = socialUserConnectionRepository.findAllByUserIdAndProviderIdOrderByRankAsc(userId, providerId); 
     return socialUserConnections.stream() 
      .mapToDouble(SocialUserConnection::getRank) 
      .max() 
      .orElse(0D) + 1D; 
    } 

    private Connection<?> findPrimaryConnection(String providerId) { 
     List<SocialUserConnection> socialUserConnections = socialUserConnectionRepository.findAllByUserIdAndProviderIdOrderByRankAsc(userId, providerId); 
     if (socialUserConnections.size() > 0) { 
      return socialUserConnectionToConnection(socialUserConnections.get(0)); 
     } else { 
      return null; 
     } 
    } 

    private SocialUserConnection connectionToUserSocialConnection(Connection<?> connection, Long rank) { 
     ConnectionData connectionData = connection.createData(); 
     return new SocialUserConnection(
      userId, 
      connection.fetchUserProfile().getEmail(), 
      connection.getKey().getProviderId(), 
      connection.getKey().getProviderUserId(), 
      rank, 
      connection.getDisplayName(), 
      connection.getProfileUrl(), 
      connection.getImageUrl(), 
      connectionData.getAccessToken(), 
      connectionData.getSecret(), 
      connectionData.getRefreshToken(), 
      connectionData.getExpireTime() 
     ); 
    } 

    private List<Connection<?>> providerUserIdsToConnections(String providerId, List<String> providerUserIds) { 
     List<SocialUserConnection> socialUserConnections = socialUserConnectionRepository.findAllByUserIdAndProviderIdAndProviderUserIdIn(userId, providerId, providerUserIds); 
     return socialUserConnectionsToConnections(socialUserConnections); 
    } 

    private List<Connection<?>> socialUserConnectionsToConnections(List<SocialUserConnection> socialUserConnections) { 
     return socialUserConnections.stream() 
      .map(this::socialUserConnectionToConnection) 
      .collect(Collectors.toList()); 
    } 

    private Connection<?> socialUserConnectionToConnection(SocialUserConnection socialUserConnection) { 
     ConnectionData connectionData = new ConnectionData(socialUserConnection.getProviderId(), 
      socialUserConnection.getProviderUserId(), 
      socialUserConnection.getDisplayName(), 
      socialUserConnection.getProfileURL(), 
      socialUserConnection.getImageURL(), 
      socialUserConnection.getAccessToken(), 
      socialUserConnection.getSecret(), 
      socialUserConnection.getRefreshToken(), 
      socialUserConnection.getExpireTime()); 
     ConnectionFactory<?> connectionFactory = connectionFactoryLocator.getConnectionFactory(connectionData.getProviderId()); 
     return connectionFactory.createConnection(connectionData); 
    } 

    private <A> String getProviderId(Class<A> apiType) { 
     return connectionFactoryLocator.getConnectionFactory(apiType).getProviderId(); 
    } 
} 

とUsersConnectionRepository(http://pastebin.com/7UzsndJq

をオーバーライドします。

public class FacebookCustomConnectInterceptor implements ConnectInterceptor<Facebook> { 

    private final Logger log = LoggerFactory.getLogger(FacebookCustomConnectInterceptor.class); 

    @Inject 
    SocialService socialService; 

    @Inject 
    CustomSocialUsersConnectionRepository customSocialUsersConnectionRepository; 

    @Inject 
    SocialUserConnectionRepository socialUserConnectionRepository; 

    @Override 
    public void preConnect(ConnectionFactory<Facebook> connectionFactory, MultiValueMap<String, String> valueMap, WebRequest request) { 
     // events before connection 
    } 
    @Override 
    public void postConnect(Connection<Facebook> connection, WebRequest request) { 
     UserProfile userProfile = connection.fetchUserProfile(); 


     socialService.loginOrCreateFacebookUser(userProfile); 

    } 
} 

public void loginOrCreateFacebookUser(UserProfile userProfile) { 

     SocialUserConnection socialUserConnection = socialUserConnectionRepository.findOneByEmailAndProviderId(userProfile.getEmail(), "facebook"); 

     Optional<User> foundUser = userRepository.findByUsername(socialUserConnection.getEmail()); 

     User user = new User(); 
     if(!foundUser.isPresent()) { 
      user.setUsername(socialUserConnection.getEmail()); 
      user.setEmail(socialUserConnection.getEmail()); 
      user.setPassword(RandomUtil.generatePassword()); 
      user.setActivated(true); 
      Authority authority = authorityRepository.findOne("ROLE_USER"); 
      Set<Authority> authorities = new HashSet<>(); 
      authorities.add(authority); 
      user.setAuthorities(authorities); 

      user = userRepository.save(user); 
     } 
     else { 
      user = foundUser.get(); 
     } 

     String lowercaseLogin = user.getUsername().toLowerCase(); 
     List<GrantedAuthority> grantedAuthorities = user.getAuthorities().stream() 
       .map(authority -> new SimpleGrantedAuthority(authority.getName())) 
       .collect(Collectors.toList()); 
     UserDetails userDetails = new org.springframework.security.core.userdetails.User(lowercaseLogin, 
       user.getPassword(), 
       grantedAuthorities); 
     Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); 

     //SecurityContextHolder.clearContext(); 
     SecurityContextHolder.getContext().setAuthentication(authentication); 
    } 

問題は、postConnectでいくつかの機能を実行しようとするときです。私はこれを行うときにエラーが発生しました: WARN 3232 --- [nio-8080-exec-3] o.s.sconnect.web.ConnectController:OAuth2コールバック(null)を処理中に例外が発生しました。 facebook接続ステータスページにリダイレクトします。

フルスタック: http://pastebin.com/QXGtv3xe

私は2つの以上のリンク:)

私は春ブーツ1.3.5

+0

私のFacebookアプリのOAuth2を使用を投稿することはできませんconfig: http://i.stack.imgur.com/6zAxh.jpg – CSniper

答えて

0

https://github.com/spring-guides/gs-accessing-facebook/issues/25

Create a your own User Class with the fields you required. 
(Fields that are able to use: 
{ "id", "about", "age_range", "birthday", "context", "cover", "currency", "devices", "education", "email", "favorite_athletes", "favorite_teams", "first_name", "gender", "hometown", "inspirational_people", "installed", "install_type", "is_verified", "languages", "last_name", "link", "locale", "location", "meeting_for", "middle_name", "name", "name_format", "political", "quotes", "payment_pricepoints", "relationship_status", "religion", "security_settings", "significant_other", "sports", "test_group", "timezone", "third_party_id", "updated_time", "verified", "video_upload_limits", "viewer_can_send_gift", "website", "work"}) 

Replace the code similar to follow: 
String [] fields = { "id", "email", "first_name", "last_name" }; //Depends on which field you want. 
User userProfile = facebook.fetchObject("me", User.class, fields); 
関連する問題