Page 2 of 2 FirstFirst 12
Results 11 to 20 of 20

Thread: Facebook Provider Sign-in Problem.

  1. #11
    Join Date
    Aug 2004
    Posts
    1,075

    Default

    Ah, I see. Then I certainly can help.

    One of the main benefits of Spring Social is that (unless you want to), you don't ever have to deal with OAuth yourself. You configure the connection factory with the app's key and secret and then you're done dealing with OAuth. You can then ask the connection repository for a connection and from that get the API binding.

    Have a look at the Spring Social Showcase sample, specifically at SocialConfig.java (https://github.com/SpringSource/spri...ialConfig.java). This shows how the connection repository can give you a Facebook API binding...here's a snippet from that file:

    Code:
    @Bean
    @Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
    public Facebook facebook() {
    Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class);
    return facebook != null ? facebook.getApi() : new FacebookTemplate();
    }
    Craig Walls
    Spring Social Project Lead

  2. #12
    Join Date
    Mar 2012
    Location
    San Francisco
    Posts
    12

    Default

    here lies my problem. when i try to do this . my facebook object is null. its not finding the connection in the connectionRepository. remember i had previously modified my application to user a local userconnections table. i'm not sure if this is what is causing the problem.

  3. #13
    Join Date
    Aug 2004
    Posts
    1,075

    Default

    That doesn't make much sense to me: You say that the connections are being written to the UserConnection table, but the connection repository can't find them? If it's the same connection repository wired with the same data source, then I don't see how the connection repository wouldn't be able to find that table. The connection repository was responsible for storing those connections in the first place, so why couldn't it find them when you later ask for them?

    Would you mind posting the pertinent configuration here? At this point I'm just speculating (and not even able to do that effectively)...perhaps seeing how you've configured these beans would make a difference.
    Craig Walls
    Spring Social Project Lead

  4. #14
    Join Date
    Mar 2012
    Location
    San Francisco
    Posts
    12

    Default

    this is my socialConfig class :

    Code:
    /*
     * Copyright 2011 the original author or authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package com.teenjobs.web.controllers.social.config;
    
    import javax.inject.Inject;
    import javax.sql.DataSource;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Scope;
    import org.springframework.context.annotation.ScopedProxyMode;
    import org.springframework.core.env.Environment;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.crypto.encrypt.Encryptors;
    import org.springframework.security.web.savedrequest.RequestCache;
    import org.springframework.social.connect.Connection;
    import org.springframework.social.connect.ConnectionFactoryLocator;
    import org.springframework.social.connect.ConnectionRepository;
    import org.springframework.social.connect.UsersConnectionRepository;
    import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
    import org.springframework.social.connect.support.ConnectionFactoryRegistry;
    import org.springframework.social.connect.web.ConnectController;
    import org.springframework.social.connect.web.ProviderSignInController;
    import org.springframework.social.facebook.api.Facebook;
    import org.springframework.social.facebook.api.impl.FacebookTemplate;
    import org.springframework.social.facebook.connect.FacebookConnectionFactory;
    import org.springframework.social.linkedin.api.LinkedIn;
    import org.springframework.social.linkedin.connect.LinkedInConnectionFactory;
    
    import com.teenjobs.persistence.repository.AccountRepository;
    import com.teenjobs.web.social.facebook.PostToWallAfterConnectInterceptor;
    import com.teenjobs.web.social.signin.SimpleSignInAdapter;
    import com.teenjobs.web.social.twitter.TweetAfterConnectInterceptor;
    import org.springframework.social.twitter.api.Twitter;
    import org.springframework.social.twitter.api.impl.TwitterTemplate;
    import org.springframework.social.twitter.connect.TwitterConnectionFactory;
    
    /**
     * Spring Social Configuration.
     * @author Craig Walls
     */
    @Configuration
    public class SocialConfig {
    
    	@Inject
    	private Environment environment;
    
    	@Inject
    	private DataSource dataSource;
    	
    	@Inject
    	private AccountRepository accountrepository;
    
    	@Bean
    	@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES) 
    	public ConnectionFactoryLocator connectionFactoryLocator() {
    		ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
    		registry.addConnectionFactory(new TwitterConnectionFactory(environment.getProperty("twitter.consumerKey"),
    				environment.getProperty("twitter.consumerSecret")));
    		registry.addConnectionFactory(new FacebookConnectionFactory(environment.getProperty("facebook.clientId"),
    				environment.getProperty("facebook.clientSecret")));
    		registry.addConnectionFactory(new LinkedInConnectionFactory(environment.getProperty("linkedin.consumerKey"),
    				environment.getProperty("linkedin.consumerSecret")));
    		return registry;
    	}
    
    	@Bean
    	@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES) 
    	public UsersConnectionRepository usersConnectionRepository() {
    		return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator(), Encryptors.noOpText());
    	}
    
    	@Bean
    	@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)	
    	public ConnectionRepository connectionRepository() {
    		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    		if (authentication == null) {
    			throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
    		}
    		return usersConnectionRepository().createConnectionRepository(authentication.getName());
    	}
    
    	@Bean
    	@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)	
    	public Facebook facebook() {
    		Connection<Facebook> facebook = connectionRepository().findPrimaryConnection(Facebook.class);
    		return facebook != null ? facebook.getApi() : new FacebookTemplate();
    	}
    	
    	@Bean
    	@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)	
    	public Twitter twitter() {
    		Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class);
    		return twitter != null ? twitter.getApi() : new TwitterTemplate();
    	}
    
    	@Bean
    	@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)	
    	public LinkedIn linkedin() {
    		Connection<LinkedIn> linkedin = connectionRepository().findPrimaryConnection(LinkedIn.class);
    		return linkedin != null ? linkedin.getApi() : null;
    	}
    
    	@Bean
    	public ConnectController connectController() {
    		ConnectController connectController = new ConnectController(connectionFactoryLocator(), connectionRepository());
    		connectController.addInterceptor(new PostToWallAfterConnectInterceptor());
    		connectController.addInterceptor(new TweetAfterConnectInterceptor());
    		return connectController;
    	}
    
    	@Bean
    	public ProviderSignInController providerSignInController(RequestCache requestCache) {
    		ProviderSignInController providerSignInController = new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache,accountrepository));
    	    providerSignInController.setPostSignInUrl("/"); 
    		providerSignInController.setSignUpUrl("/signup/teens");
    		return providerSignInController;
    	}
    
    }

    and my mainconfig for the spring social.

    Code:
    /*
     * Copyright 2011 the original author or authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package com.teenjobs.web.controllers.social.config;
    
    import javax.sql.DataSource;
    
    
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    /**
     * Main configuration class for the application.
     * Turns on @Component scanning, loads externalized application.properties, and sets up the database.
     * @author Craig Walls
     */
    @Configuration
    @ComponentScan(basePackages = "com.teenjobs.web", excludeFilters = { @Filter(Configuration.class) })
    @PropertySource("classpath:com/teenjobs/web/controllers/social/config/application.properties")
    @EnableTransactionManagement
    public class MainConfig {
    
    	 private JdbcTemplate jdbcTemplate;
    	private DataSourceTransactionManager transactionManager;
    	 
    
    	    @Autowired
    	    public void setDataSource(DataSource dataSource) {
    	        this.jdbcTemplate = new JdbcTemplate(dataSource);
    	        this.transactionManager = new DataSourceTransactionManager(dataSource);
    	    }
    	
    	
    
    }
    basically all i did was set the dataSource to my db. which is configured in an xml file.
    Last edited by habuma; Apr 24th, 2012 at 08:35 AM.

  5. #15
    Join Date
    Aug 2004
    Posts
    1,075

    Default

    I must admit that I'm a bit stumped. I'm sure there's some key info that I'm either overlooking or isn't presented here. I've stared at this code you've shared for quite awhile and see nothing obvious that's out of place.

    But it seems to me that if in the course of a provider sign-in a connection is, in fact, created in the database, then that connection should be found later when findByPrimaryConnection() is called.

    That assumes, of course, that the authenticated user is the same authenticated user for which the connection was created. Ultimately, the query performed is as follows:

    Code:
    select userId, providerId, providerUserId, displayName, profileUrl, imageUrl, accessToken, secret, refreshToken, expireTime from UserConnection where userId = ? and providerId = ? and rank = 1
    Where the userId is the same as whatever value is passed into createConnectionRepository() and providerId is whatever the provider connection factory says it is for the given API interface (in the case of Facebook, it will be "facebook").

    Can we be sure that the connection is created for the very same user for whom the authentication is retrieved when creating the connection repository? More specifically, can we confirm that the userId field in the UserConnection table holds the same value as the value returned from authentication.getName()?

    To help with that, you might want to do a bit of debugging in the connectionRepository() method of your SocialConfig.java and then compare what is passed into createConnectionRepository() with what is in the userId field in the UserConnection table.

    That's the only theory I have right now. Once your eliminate or confirm that as the issue, I can keep looking.
    Craig Walls
    Spring Social Project Lead

  6. #16
    Join Date
    Mar 2012
    Location
    San Francisco
    Posts
    12

    Default

    Problem Solved !

    Your were exactly correct. I was taking for granted that authentication.getName() was returning the email address.

    In my system , the user's email address is what i use in my userconnection table as seen here :

    if (account != null) {
    SignInUtils.signin(account);
    ProviderSignInUtils.handlePostSignUp(account.getEm ail(), request);
    return "redirect:/";
    }

    Therefore the the authentication.getName() was not returning my username in my table i.e. the user's email address .

    So i modified the createConnectionRepository method to suit my system. I have a method that can get an account object for the currently authenticated user. So i call the method and get the user's email address from the object , and use this email address to create the connectionrepository as seen below :

    Account account = AccountUtils.getCurrentAccount();
    String myAuth = authentication.getName();
    if (account !=null) {
    myAuth = account.getEmail();
    }


    return usersConnectionRepository().createConnectionReposi tory(myAuth);


    Thank you very much for your help.

  7. #17
    Join Date
    Aug 2004
    Posts
    1,075

    Default

    I'm glad you sorted it out. I wasn't sure where to head to if that didn't work.

    To be clear: You say you changed the createConnectionRepository() method, but would it be more correct to say that you changed the configuration for connectionRepository() to call createConnectionRepository() with the right value? Just want to be sure that you didn't actually change JdbcUsersConnectionRepository's createConnectionRepository() method, as that would be completely unnecessary.
    Craig Walls
    Spring Social Project Lead

  8. #18
    Join Date
    Mar 2012
    Location
    San Francisco
    Posts
    12

    Default

    yeah thats what i mean. i didn't actually change the method. just the value that it uses when i call it.

    Thanks again.

  9. #19
    Join Date
    Oct 2012
    Posts
    3

    Default

    Quote Originally Posted by habuma View Post
    With Spring Social Showcase, it's using an in-memory database, which is great for demos and development, but horrible for production for the reasons you've just given. I'm assuming that the reason your connections are lost is because you're using the embedded database. Rather than use the embedded database, you should use a datasource that's tied to a real DB.
    Quote Originally Posted by modeminho View Post
    Thank you Craig , I got it working by creating the userconnection table in my db and pointing the datasource to it. Everything works fine now. The only thing i noticed when i created the table is that i had to change refreshtoken and secret fields from not null to allow nulls because this was throwing an error.

    Thanks again for your help.
    I have spring social showcase example here with in-memory database, so how to configure it so I can connect with table member in my DB?, I already make table connection in my member DB

  10. #20
    Join Date
    Aug 2004
    Posts
    1,075

    Default

    ardiavernus: I've already answered your question in a separate thread. Let's not continue the discussion in this thread.
    Craig Walls
    Spring Social Project Lead

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •