Integrate Spring Security with Facebook Login
Solution 1
I don't think you should deal with Facebook manually. You can a really easy library: https://github.com/pac4j/spring-security-pac4j to authenticate for OAuth (Facebook, Twitter, Google...), CAS, SAML, OpenID (Connect) and GAE. See the demo: https://github.com/pac4j/spring-security-pac4j-demo
Solution 2
Daniel could you please elaborate where are you getting stuck. I used the same stack for integrating facebook login. But I did not use Spring Social. I believe it's not required.
Steps to integrate facebook login with the existing login.
- Use the facebook javascript plugin in your jsp for facebook login.
- Once the user approves your app. OAuth generates an auth token, using that fetch the email id of the client using graph API.
- Send the email id to the server using Ajax.
- Compare the email id sent to the server side with the email id in the database.
- If the email id is same login the user.
Authentication token is temporary so I find it pointless sending it to the server side or saving in db. It is saved locally on the client side. And the fb javascript plugin takes care of it. This way it saves you the hassle of implementing spring social facebook.
I see you are using the controller for facebook login, it's not required, trust me using the fb javascript plugin is really simple & easy.
Daniel Robertus
Updated on June 04, 2022Comments
-
Daniel Robertus almost 2 years
I use Spring MVC and Spring Security for my project.. This using my own user data for authentication. But now i trying to integrate with Facebook. i have created app on Facebook means i got Client ID and client Secret.. I also read some questions in SO and some documents but still stuck...
i create controller to Login with Facebook :
import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/login/") public class LoginController { String fb_app_id="my_client_id"; String redirect_url="localhost:8888"; String state="public_profile,email,user_friends"; String key="my_client_secret"; @RequestMapping("/facebook") public String login( ModelMap model) { String url="https://www.facebook.com/dialog/oauth/?" + "client_id=" + fb_app_id + "&redirect_uri=" + redirect_url + "&scope=email,publish_stream,user_about_me,friends_about_me" + "&state=" + key + "&display=page" + "&response_type=code"; return "redirect:"+url; } }
i think it works because when i try to connect, i can show my name with Javascript below:
function testAPI() { console.log('Welcome! Fetching your information.... '); FB.api('/me', function(response) { console.log('Good to see you, ' + response.name + '.'); document.getElementById('status').innerHTML = 'Good to see you, ' + response.name; }); }
But i still confuse how to integrate it with Spring Security. If anyone have any examples i will appreciate...
This is my spring-security.xml
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <http pattern="/common/*" security="none" /> <http auto-config="true"> <intercept-url pattern="/maintenance/*" access="ROLE_USER" /> <intercept-url pattern="/_ah/*" access="ROLE_USER" /> <intercept-url pattern="/predict/*" access="ROLE_USER" /> <form-login login-page='/' default-target-url='/predict/list' login-processing-url="/login_check" authentication-failure-url="/index?login_error=2" always-use-default-target="true" /> <logout logout-url="/logout" logout-success-url="/index" /> <!-- <custom-filter ref="socialAuthenticationFilter" before="PRE_AUTH_FILTER" /> --> <!-- <custom-filter before="FORM_LOGIN_FILTER" ref="facebookAuthenticationFilter" /> --> </http> <authentication-manager> <authentication-provider ref="gaeAuthenticationProvider" /> <!-- <authentication-provider ref="authenticationProviderFacebook"> </authentication-provider>--> </authentication-manager> <beans:bean id="gaeAuthenticationProvider" class="com.games.predictor.security.AuthenticationProvider" /> </beans:beans>
i have my own class to Authenticate to userdata with JPA...
package com.games.predictor.security; import java.util.List; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.authority.SimpleGrantedAuthority; import com.games.predictor.UserDAO; public class AuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { //private SecurityDao securityDao; @Override protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { final String password = authentication.getCredentials().toString(); System.out.println(username+"===="+password); //This line for validating user with database boolean isValidUser = UserDAO.INSTANCE.isValidUser(username, password); if (isValidUser) { final List<SimpleGrantedAuthority> authorities = UserDAO.INSTANCE.getAuthoritiesByUser(username); //User u=new User(username,password,); return new User(username, password, true, true, true, true, authorities); } else { authentication.setAuthenticated(false); throw new BadCredentialsException("Username/Password does not match for " + authentication.getPrincipal()); } } @Override protected void additionalAuthenticationChecks(UserDetails arg0, UsernamePasswordAuthenticationToken arg1) throws AuthenticationException { // TODO Auto-generated method stub } }
I did some research in last few days but still stuck.
My Project Stack : Java, Spring MVC, Spring Security, Google App Engine, Google Data Store, JPA. (Spring Social Core and Spring Social Facebook Added)
-
Daniel Robertus almost 10 yearsHi, Thanks for your answer.. My problem is when integrating Facebook Login with Spring Security Session. I see some people use it with spring social and spring security. But i have problem when trying implementing one of that sample.
-
2low.samurai over 9 yearsUnderdog misses this-you should not fetch email id of the client that was generated on the client side, because that could be easily modified by some other email and thus person that should not have entrance can get entrance. Once auth user token is returned, you should send that token to the server side, where you need to check that this token is still the token that was generated , as recomended by facebook here developers.facebook.com/docs/facebook-login/login-flow-for-web/… . Once you confirm this, you can login this facebook user as one of your user it the user exists.