javaspringspring-securityspring-socialspring-social-facebook

Spring social Facebook Profile provides only ID and name


I have an issue with getting parameters others than id and name using spring-social.

Dependencies:

    <!-- Spring Social -->
    <dependency>
        <groupId>org.springframework.social</groupId>
        <artifactId>spring-social-config</artifactId>
        <version>1.1.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.social</groupId>
        <artifactId>spring-social-core</artifactId>
        <version>1.1.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.social</groupId>
        <artifactId>spring-social-security</artifactId>
        <version>1.1.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.social</groupId>
        <artifactId>spring-social-web</artifactId>
        <version>1.1.2.RELEASE</version>
    </dependency>

    <!-- Spring Social Facebook -->
    <dependency>
        <groupId>org.springframework.social</groupId>
        <artifactId>spring-social-facebook</artifactId>
        <version>2.0.3.RELEASE</version>
    </dependency>

Configuration:

<security:http ...>
...
    <security:custom-filter before="PRE_AUTH_FILTER" ref="socialAuthenticationFilter" />
...
</security:http>
<security:authentication-manager alias="authenticationManager">
    ...
    <security:authentication-provider ref="socialAuthenticationProvider" />
</security:authentication-manager>
<bean id="socialAuthenticationProvider" class="org.springframework.social.security.SocialAuthenticationProvider">
    <constructor-arg ref="inMemoryUsersConnectionRepository"/>
    <constructor-arg ref="socialUserDetailsService"/>
</bean>

<bean id="inMemoryUsersConnectionRepository"
      class="org.springframework.social.connect.mem.InMemoryUsersConnectionRepository">
    <constructor-arg name="connectionFactoryLocator" ref="connectionFactoryLocator"/>
    <property name="connectionSignUp" ref="connectionSignUp"/>
</bean>

<bean id="connectionFactoryLocator"
      class="org.springframework.social.security.SocialAuthenticationServiceRegistry">
    <property name="authenticationServices">
        <list>
            <ref bean="facebookAuthenticationService"/>
        </list>
    </property>
</bean>

<bean id="socialAuthenticationFilter" class="org.springframework.social.security.SocialAuthenticationFilter">
    <constructor-arg name="authManager" ref="authenticationManager"/>
    <constructor-arg name="userIdSource" ref="userIdSource"/>
    <constructor-arg name="usersConnectionRepository" ref="inMemoryUsersConnectionRepository"/>
    <constructor-arg name="authServiceLocator" ref="connectionFactoryLocator"/>
    <property name="authenticationSuccessHandler" ref="loginGuidAuthenticationSuccessHandler"/>
</bean>

<bean id="userIdSource" class="org.springframework.social.security.AuthenticationNameUserIdSource"/>

<bean id="facebookAuthenticationService"
      class="org.springframework.social.facebook.security.FacebookAuthenticationService">
    <constructor-arg name="apiKey" value="<myKey>"/>
    <constructor-arg name="appSecret" value="<mySecret>"/>
    <property name="defaultScope" value="email"/>
</bean>

<bean id="connectionSignUp" class="my.package.DefaultConnectionSignUp"/>

I have my own implementations of some of the required services, which I don't think are relevant. When I debug execute method in my implementation of ConnectionSignUp all of the users fields are null except for name and id.

@Override
public String execute(Connection<?> connection) {
    Connection<Facebook> fbConnection = (Connection<Facebook>) connection;
    fbConnection.getApi().userOperations().getUserProfile().getEmail(); //null
    fbConnection.getApi().userOperations().getUserProfile().getFirstName(); //null
    fbConnection.fetchUserProfile().getEmail(); //null
    fbConnection.fetchObject("me", User.class); //email == null
    ...
}

My jsp form:

    <form name='facebookSocialloginForm'
          action="<c:url value='/auth/facebook' />" method='POST'>
        <input type="hidden" name="scope" 
            value="public_profile,email,user_about_me,user_birthday,user_likes"/>
        ...
    </form>

I can access users private posts and likes though. On my facebook account it says that the app has access to the email and other informations.

Any suggestions? If I've missed something important, please ask and I'll provide more info.


Solution

  • changes in facebook api might have caused this. Try the code below:

    UserOperations userOperations = facebook.userOperations();
                String [] fields = { "id", "email",  "first_name", "last_name" };
                org.springframework.social.facebook.api.User profile = facebook.fetchObject
                        ("me", org.springframework.social.facebook.api.User.class, fields);