我使用Spring Security 2.0-RC4和Spring Security 0.15.2-CORE2的Facebook身份验证,允许用户通过Facebook登录进行身份验证。我要求额外的FB许可"电子邮件"因为我使用电子邮件作为我的User类的主键,所以如果用户未选择电子邮件权限,我需要中止登录。目前,我在FacebookAuthService.create()
中检查空电子邮件,如果未设置电子邮件,则返回null。
在正常情况下一切正常。登录成功,我创建了新的用户和FacebookUser记录,并且用Facebook用户的电子邮件地址更新了我的用户对象的电子邮件属性。但是,如果用户在登录期间选择删除电子邮件权限,则会遇到问题。
在我的FacebookAuthService.create()
中,我检查是否返回了电子邮件(类似于in this question),如果没有,则返回null以中止身份验证过程:
FacebookUser create(FacebookAuthToken token) {
Facebook facebook
FacebookProfile fbProfile
try {
facebook = new FacebookTemplate(token.accessToken.accessToken)
fbProfile = facebook.userOperations().userProfile
} catch (org.springframework.social.ApiException apiex) {
return null
}
String email = fbProfile.email
if (!email) {
return null
}
...
当电子邮件为空并且我返回null时,我的安全状态似乎搞砸了。我的控制器上有一个beforeInterceptor,在我从create()返回null之后调用它:
def beforeInterceptor = {
def user = springSecurityService.currentUser
log.trace("${user?.email} - End action ${controllerName}Controller.${actionName}() : returns $model, view ${modelAndView?.viewName}")
}
getCurrentUser()应该返回null,而是抛出异常:
org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver - NullPointerException occurred when processing request: [GET] /rar/user/home
Cannot get property 'username' on null object. Stacktrace follows:
java.lang.NullPointerException: Cannot get property 'username' on null object
at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:56)
at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:169)
at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:227)
at grails.plugin.springsecurity.SpringSecurityService.getCurrentUser(SpringSecurityService.groovy:87)
at grails.plugin.springsecurity.SpringSecurityService$$FastClassBySpringCGLIB$$6e53ab8e.invoke(<generated>)
...
SpringSecurityService似乎认为有人已登录,因为getCurrentUser()
对isLoggedIn()
的调用返回true,这会导致稍后当principal为null并且访问属性时出现异常null主要对象。
我是否应该以不同的方式中止Facebook登录过程,而不是从FacebookAuthService.create()
返回null?
答案 0 :(得分:0)
通过从FacebookAuthService.create()
抛出异常而不是在删除电子邮件权限时返回null来解决此问题。
我的create()
现在包含以下代码段:
if (!email) {
def grailsWebRequest = WebUtils.retrieveGrailsWebRequest()
def flash = grailsWebRequest.flashScope
flash.message = 'Login to Facebook failed. We must have access to your email address in order to proceed with login.'
throw new InsufficientAuthenticationException()
}