我想在使用 Spring Security 的应用程序中使用 facebook 登录 + DB 身份验证。
所以我在 index.jsp 页面中添加了一个发送请求的 fb 按钮,例如,
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.' + response.email);
window.location = "<%=request.getContextPath()%>/j_spring_facebook_security_check";
});
}
applicationContext-Security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans">
//spring security 3.
<security:http auto-config="true" use-expressions="true" access-denied-page="/accessDenied.jsp">
<security:form-login login-page="/index.jsp"
default-target-url="/jsp/home.jsp"
authentication-failure-handler-ref="authenticationFailureHandler"/>
<security:intercept-url pattern="/jsp/listInBetweenPlaces.jsp"
access="permitAll" />
<security:intercept-url pattern="/jsp/home.jsp"
access="permitAll" />
<security:intercept-url pattern="/index.jsp"
access="permitAll" />
<security:intercept-url pattern="/jsp/*"
access="isAuthenticated()" />
<security:logout logout-url="/j_spring_security_logout" logout-success-url="/index.jsp?logout=success"
invalidate-session="true" />
<security:custom-filter before="FORM_LOGIN_FILTER"
ref="facebookAuthenticationFilter" />
</security:http>
<bean id="facebookAuthenticationFilter" class="org.springframework.security.facebook.FacebookAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name = "authenticationSuccessHandler">
<bean class = "org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<property name = "defaultTargetUrl" value = "/jsp/home.jsp" />
<property name = "alwaysUseDefaultTargetUrl" value = "true" />
</bean>
</property>
<property name = "authenticationFailureHandler">
<bean class = "org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name = "defaultFailureUrl" value = "/fb/failure.jsp" />
</bean>
</property>
</bean>
<bean id="authenticationProviderFacebook" class="org.springframework.security.facebook.FacebookAuthenticationProvider">
<property name="roles" value="ROLE_FACEBOOK_USER" />
</bean>
<bean id="facebookHelper" class="org.springframework.security.facebook.FacebookHelper">
<property name="apiKey" value="my_api_key" />
<property name="secret" value="my_secret_key" />
</bean>
<bean id="customUserDetailsService" class="com.onmobile.carpool.authentication.CustomUserDetailsService">
<!-- <property name="carpoolService" ref="carpoolServiceImpl" /> -->
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder hash="md5" />
</security:authentication-provider>
<security:authentication-provider ref="authenticationProviderFacebook">
</security:authentication-provider>
</security:authentication-manager>
</beans>
FacebookAuthenticationFilter.java:
public class FacebookAuthenticationFilter extends
AbstractAuthenticationProcessingFilter implements
ApplicationContextAware {
public static final String DEFAULT_FILTER_PROCESS_URL = "/j_spring_facebook_security_check";
private FacebookHelper facebookHelper = null ;
private ApplicationContext ctx;
protected FacebookAuthenticationFilter() {
super(DEFAULT_FILTER_PROCESS_URL);
}
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException,
IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if(facebookHelper == null){
facebookHelper = (FacebookHelper) ctx
.getBean("facebookHelper");
}
Long uid = null;
String sessionkey = null ;
try {
uid = facebookHelper.getLoggedInUserId(request, response);
sessionkey = facebookHelper.lookupSessionKey(request);
} catch (FacebookUserNotConnected e) {
throw new AuthenticationCredentialsNotFoundException(
"Facebook user not connected", e);
}
FacebookAuthenticationToken token = new FacebookAuthenticationToken(uid);
token.setSessionkey(sessionkey);
token.setDetails(authenticationDetailsSource.buildDetails(request));
AuthenticationManager authenticationManager = getAuthenticationManager();
Authentication authentication = authenticationManager
.authenticate(token);
return authentication;
}
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
this.ctx = ctx;
}
public FacebookHelper getFacebookHelper() {
return facebookHelper;
}
public void setFacebookHelper(FacebookHelper facebookHelper) {
this.facebookHelper = facebookHelper;
}
}
我总是遇到这个电话的问题:
uid = facebookHelper.getLoggedInUserId(request, response);
getLoggedInUserId
FacebookHelper.java 中的详细信息:
public Long getLoggedInUserId(HttpServletRequest request,
HttpServletResponse response) throws FacebookUserNotConnected {
FacebookWebappHelper<Document> facebook = new FacebookWebappHelper<Document>(
request, response, apiKey, secret);
Long uid = facebook.getUser();
if (uid == null)
throw new FacebookUserNotConnected(
"Facebook user id could not be obtained");
return uid;
}
下面的行总是评估为 null 因为它抛出异常:
Long uid = facebook.getUser();
我从下面的链接中学习了 Facebook 相关课程,
我的需要是让用户可以通过 DB 检查或通过 FB 身份验证登录到我的应用程序。
我无法继续这样做,有人可以指出我缺少什么。我总是被重定向到 failure.jsp。我需要在 FB 帐户中启用什么吗?或者我将一些不正确的数据从 UI 传递到过滤器?
我无法在任何地方找到完整的教程,有人可以指出正确的链接。