I've been stuck on this issue for quite a while, and I've re-formulated my question a few times. I'll be explicit with this one, providing the implementation below:
index.xhtml, the short version.
...
<f:event listener="#{userBacking.pullUserInfo}" type="preRenderView" />
<h:commandLink action="#{userBacking.login()}" value="Login" rendered="#{!userBacking.isLoggedIn()}"/>
<h:commandLink action="#{userBacking.logout()}" value="Logout" rendered="#{userBacking.isLoggedIn()}" />
<h:outputText rendered="#{userBacking.isLoggedIn()}" value="#{userBacking.userProfile.fullName}" />
...
UserBacking.java
/**
*
* @author ggrec
*
*/
@ManagedBean
@SessionScoped
public class UserBacking implements Serializable
{
// ==================== 2. Instance Fields ============================
private static final long serialVersionUID = -2262690225818595135L;
/**
* This is static for now. In the future, Google (and others) may be implemented.
*/
public static final String SOCIAL_PROVIDER_ID = "facebook"; //$NON-NLS-1$
// ==================== 2. Instance Fields ============================
private SocialAuthManager socialAuthManager;
private Profile userProfile;
// ==================== 6. Action Methods =============================
public void login() throws Exception
{
final Properties props = System.getProperties();
props.put("graph.facebook.com.consumer_key", FACEBOOK_APP_ID); //$NON-NLS-1$
props.put("graph.facebook.com.consumer_secret", FACEBOOK_APP_SECRET); //$NON-NLS-1$
props.put("graph.facebook.com.custom_permissions", "email"); //$NON-NLS-1$ //$NON-NLS-2$
final SocialAuthConfig config = SocialAuthConfig.getDefault();
config.load(props);
socialAuthManager = new SocialAuthManager();
socialAuthManager.setSocialAuthConfig(config);
final String authenticationURL = socialAuthManager.getAuthenticationUrl(SOCIAL_PROVIDER_ID, successURL());
ContextHelper.redirect(authenticationURL);
}
public void logout() throws Exception
{
socialAuthManager.disconnectProvider(SOCIAL_PROVIDER_ID);
ContextHelper.invalidateSession();
}
/*
* Should fill up the profile, if a redirect from Facebook appers. Uhhh....
*/
public void pullUserInfo() throws Exception
{
if (userProfile == null && socialAuthManager != null)
{
final HttpServletRequest req = (HttpServletRequest) ContextHelper.ectx().getRequest();
final Map<String, String> reqParam = SocialAuthUtil.getRequestParametersMap(req);
final AuthProvider authProvider = socialAuthManager.connect(reqParam);
userProfile = authProvider.getUserProfile();
ContextHelper.redirect( ContextHelper.getContextPath() );
}
}
// ==================== 7. Getters & Setters ======================
public Profile getUserProfile()
{
return userProfile;
}
public boolean isLoggedIn()
{
return userProfile != null;
}
// ==================== 9. Convenience Methods ========================
private static String successURL()
{
return IApplicationConstants.APP_PSEUDO_URL + ContextHelper.getContextPath();
}
}
My story
Works fine if a Facebook session doesn't exist in the browser. If I'm already logged in, it seems that the
socialAuthManager
is NULL when acode
in the request params appears.I use
index.xhtml
for both login and callback.The
f:event
firespullUserInfo()
each time the view renders, hoping that when the method fires, acode
is provided in the request params. I am aware that this is all wrong.Can this be done with a filter (i.e. when Facebook calls back with a
code
)?I'm not the biggest JSF expert, so I might be missing some basic knowledge.
References
Mr James - Implement Facebook login in JSF using SocialAuth
How use SocialAuth with JSF to redirect?
This very pretty flowchart