Facebook Login with Spring Social using Existing User Access Token
Asked Answered
W

1

16

Here's what I currently have:

  • Spring REST service where many of the APIs require the user to be authenticated
  • A 'registration' API (/api/v1/register)
  • A 'login' API that takes username/password (/api/v1/login)
  • 'Facebook Login' API that relies on Spring Social and Spring Security to create a User Connection and log my user in (/auth/facebook)

My problem is that I want these APIs to be used by multiple clients, but the way Facebook Login is right now, it doesn't work well on mobile (works great on a website).

Here's the mobile scenario:

  • I use Facebook's iOS SDK to request permission from the user
  • Facebook returns a user access token
  • I want to send my backend service this token and have Spring Social accept it, create the User Connection, etc.

Can this be done? Or am I going to have to write my own API to persist the User Connection?

Appreciate any help!

Workwoman answered 18/4, 2015 at 2:3 Comment(0)
K
10

I had the exact same issue and here's how I made it work. You probably have a SocialConfigurer somewhere with the following:

@Configuration
@EnableSocial
public class SocialConfig implements SocialConfigurer {

    @Autowired
    private DataSource dataSource;

    @Bean
    public FacebookConnectionFactory facebookConnectionFactory() {
        FacebookConnectionFactory facebookConnectionFactory = new FacebookConnectionFactory("AppID", "AppSecret");
        facebookConnectionFactory.setScope("email");
        return facebookConnectionFactory;
    }

    @Override
    public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {
        cfConfig.addConnectionFactory(facebookConnectionFactory());
    }

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

    @Override
    public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
    }

    // Other @Bean maybe ...
}

From here, what you can do is, in a Controller/RestController, add a mapping with a RequestParam for your token that you will send to your server:

@Autowired
private FacebookConnectionFactory facebookConnectionFactory;

@Autowired
private UsersConnectionRepository usersConnectionRepository;

@RequestMapping(value = "/my-facebook-url", method = RequestMethod.POST)
public String fb(@RequestParam String token) {
    AccessGrant accessGrant = new AccessGrant(token);
    Connection<Facebook> connection = facebookConnectionFactory.createConnection(accessGrant);

    UserProfile userProfile = connection.fetchUserProfile();
    usersConnectionRepository.createConnectionRepository(userProfile.getEmail()).addConnection(connection);

    // ...

    return "Done";
}

Useful references

Kowtow answered 28/9, 2015 at 17:31 Comment(5)
Hi @Philippe! Have you this working with spring-social-facebook version 2? ThanksMazdaism
@troig, precisely yes. I also have spring-social-core/web/config/security:1.1.2 are you having any issues with it?Kowtow
Thanks again @Philippe! It worked upgrading spring-social-core version to 1.1.2 as you say. There is a bug with my previous version (1.1.0). +1Mazdaism
Hi Philippe. Unfortunately I cannot accept it because I didn't make the question. Maybe @Workwoman could considerate it. Thsnks again, in my case it worked pretty wellMazdaism
You can use FacebookTokenAuthenticationFilter which extends SocialAuthenticationFilter of Spring Social Security API. #35912223Paramo

© 2022 - 2024 — McMap. All rights reserved.