接受 facebook 登录到我的 REST API
Posted
技术标签:
【中文标题】接受 facebook 登录到我的 REST API【英文标题】:Accept facebook login into my REST API 【发布时间】:2015-02-28 23:16:52 【问题描述】:我有一个后端服务器(Java / Spring / Spring Security)。 目前,当来自移动应用程序的用户登录时,他们只需提交他们的用户名/密码,Spring Security 就会创建一个 Session 并将其分配给带有 JSESSIONID 的请求。
我们现在还将在移动应用程序“使用 Facebook 登录”上添加一个按钮。这是我对其工作原理的理解。
-
移动应用使用 facebook SDK 获取“access_token”
移动应用从 facebook 检索用户资料(姓名、姓氏、电子邮件等)
移动检查(针对我的服务器)用户名是否唯一
如果用户名唯一,请调用 MY REST api,使用类似 /login/facebook POST over SSL 并传递 access_token、电子邮件、用户名等...)
我的服务器然后检查 access_token 是否有效
GET graph.facebook.com/debug_token?
input_token=token-to-inspect
&access_token=app-token-or-admin-token
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(username, null, ROLE_USER));
如果我没有找到 UID,我只需创建一个新用户并登录该用户。
从现在开始,移动设备向服务器发出的每个请求都将具有 SESSION(由 spring security 创建和附加),并且移动应用程序已通过身份验证
有人能告诉我这是否是一种好方法吗? 我应该停止使用会话并切换到 Spring-Security-OAUTH2 吗?
编辑 1
根据 Dave 的建议,这里是更新的 spring-security 配置:
<!- handle login by providing a token-->
<security:http pattern="/login/facebook" auto-config="false" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
<security:custom-filter ref="facebookLoginFilter" position="FORM_LOGIN_FILTER"/>
<security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>
<bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/login/facebook"></constructor-arg>
</bean>
<!-- handle basic username + password logins-->
<security:http auto-config="true" use-expressions="true" entry-point-ref="forbiddenEntryPoint">
<security:form-login login-processing-url="/security_check" authentication-failure-handler-ref="authFailureHandler"
default-target-url="/" always-use-default-target="true" authentication-success-handler-ref="authSuccessHandler" />
...
my others patterns..
...
</security:http>
<bean id="forbiddenEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<bean id="authSuccessHandler" class="my.package.AuthenticationSuccessHandlerImpl"/>
<bean id="authFailureHandler" class="my.package.AuthenticationFailureHandlerImpl"/>
<bean id="facebookLoginFilter" class="pl.jcommerce.ocean.web.ws.controller.FacebookLoginFilter">
<property name="requiresAuthenticationRequestMatcher" ref="loginRequestUrlHandler"></property>
<property name="authenticationManager" ref="authManager"></property>
</bean>
<security:authentication-manager id="authManager">
<security:authentication-provider ref="facebookAuthenticationProvider" />
</security:authentication-manager>
<security:authentication-manager>
<security:authentication-provider ref="webServiceUserAuthenticationProvider" />
</security:authentication-manager>
<bean id="loginRequestUrlHandler" class="org.springframework.security.web.util.matcher.RegexRequestMatcher">
<constructor-arg index="0" value="/login/facebook" />
<constructor-arg index="1" value="POST" />
<constructor-arg index="2" value="false" />
</bean>
【问题讨论】:
为此目的实现了一个 Spring 过滤器。请参阅以下链接:“Spring Authentication Filter for Stateless REST Endpoints which use Facebook Token for authentication”github.com/ozgengunay/FBSpringSocialRESTAuth 【参考方案1】:Facebook 已经在使用 OAuth2 服务器端,并为客户端提供了自己的本机 SDK,因此我认为您在服务器中使用 OAuth2 没有任何优势,除非您的用例超出了您上面概述的范围. Spring OAuth2 也有客户端支持,但在本机应用程序中没有,所以我在原则上并没有看到你的提议有任何问题。您没有详细说明将在服务器中设置安全上下文的位置,我认为这可能是一个重要的细节——它必须发生在安全过滤器链中正确的位置才能使会话成为更新了。
【讨论】:
感谢您的回复!我认为使用 Oauth2 会更容易集成 facebook 登录。只是一个想法,我有机会从基于会话的迁移到令牌。关于我将在哪里对用户进行身份验证,这是我真的不知道该放在哪里的东西。你能否更详细地指出它在过滤器中的位置?跨度> 如果我是你,我会查看UsernamePasswordAuthenticationFilter
的实现并对其进行调整以处理不同的凭据(fb 令牌而不是用户名/密码)。然后,您可以使用addFilterAfter
在与UsernamePasswordAuthenticationFilter
相同的位置添加过滤器。
完美谢谢!这就是我所做的:创建一个扩展 UsernamePasswordAuthenticationFilter 的类并覆盖“attemptAuthentication”方法。我做了一些基本检查并创建了一个以令牌为主体的身份验证对象。然后我在我的配置中创建了这个bean,并将它传递给一个新的authenticationProvider(如果一切顺利,我将通过联系facebook图形工具来处理令牌验证我对用户进行身份验证)。最后,我在我的配置中创建了一个新的“我根据 Dave Syer 在此处的回答以及他整理的 Spring Security Angular 材料尝试了实现类似的东西。要查看示例,请参阅我的 forked github 存储库,特别是 security 包中的类。
【讨论】:
以上是关于接受 facebook 登录到我的 REST API的主要内容,如果未能解决你的问题,请参考以下文章
Facebook:当我返回我的应用程序时,登录和权限屏幕不会关闭
使用 facebook 登录并使用 oauth 2.0 对 REST api 调用进行身份验证
如何将特定登录的公共 Facebook 页面数据(应用程序)获取到我的 android 应用程序中?
如何避免要求用户一次又一次地登录(连接)到我的 Facebook 应用程序?
获得权限后的 Facebook 登录让 Safari 空白页面打开,而不是在 iOS 10 和 iOS 11 中重定向到我的应用