接受 facebook 登录到我的 REST API
Accept facebook login into my REST API
我有一个后端服务器(Java / Spring / Spring 安全)。
当前,当来自移动应用程序的用户登录时,他们只需提交他们的 username/password 和 Spring 安全创建一个会话并将其分配给具有 JSESSIONID 的请求。
我们现在在移动应用程序上也会有一个按钮 "Login with Facebook"。这是我对它的工作原理的理解。
- 移动应用使用 facebook SDK 获取 "access_token"
- 移动应用程序从 Facebook 检索用户个人资料(名字、姓氏、电子邮件等)
- 移动设备检查(针对我的服务器)用户名是否唯一
- 如果用户名是唯一的,调用 MY REST api,通过 SSL 使用类似 /login/facebook POST 并传递 access_token、电子邮件、用户名等...)
我的服务器然后检查 access_token 是否有效
GET graph.facebook.com/debug_token?
input_token={token-to-inspect}
&access_token={app-token-or-admin-token}
- 如果是,如果 facebook 返回的 UID 已经存在于我的本地数据库中,我将按照以下方式登录用户:
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(username, null, ROLE_USER));
如果我找不到 UID,我只是创建一个新用户并登录该用户。
从现在开始,移动设备向服务器发出的每个请求都将具有 SESSION(由 spring 安全性创建和附加)并且移动应用程序已通过身份验证
有人能告诉我这是不是一种好的做事方式吗?
我应该停止使用会话并切换到 Spring-Security-OAUTH2 吗?
编辑 1
根据 Dave 的建议,这里更新了 spring-安全配置:
<!- 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>
Facebook 已经在使用 OAuth2 服务器端,并为客户端提供了自己的原生 SDK,所以我看不出你在服务器端使用 OAuth2 有任何优势,除非你的用例超出了你的范围大纲如上。 Spring OAuth2 也有客户端支持,但不是在本机应用程序中,所以从原则上讲,我真的没有发现您的建议有任何问题。您没有详细说明您将在服务器中的何处设置安全上下文,我认为这可能是一个重要的细节——它必须发生在安全过滤器链中的正确位置才能使会话成为已更新。
我根据 Dave Syer 在这里的回答以及他放在一起的 Spring 安全性 Angular 材料尝试了类似的实现。要查看示例,请查看我的 forked github repo, specifically the classes in the security 包。
我有一个后端服务器(Java / Spring / Spring 安全)。 当前,当来自移动应用程序的用户登录时,他们只需提交他们的 username/password 和 Spring 安全创建一个会话并将其分配给具有 JSESSIONID 的请求。
我们现在在移动应用程序上也会有一个按钮 "Login with Facebook"。这是我对它的工作原理的理解。
- 移动应用使用 facebook SDK 获取 "access_token"
- 移动应用程序从 Facebook 检索用户个人资料(名字、姓氏、电子邮件等)
- 移动设备检查(针对我的服务器)用户名是否唯一
- 如果用户名是唯一的,调用 MY REST api,通过 SSL 使用类似 /login/facebook POST 并传递 access_token、电子邮件、用户名等...)
我的服务器然后检查 access_token 是否有效
GET graph.facebook.com/debug_token? input_token={token-to-inspect} &access_token={app-token-or-admin-token}
- 如果是,如果 facebook 返回的 UID 已经存在于我的本地数据库中,我将按照以下方式登录用户:
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(username, null, ROLE_USER));
如果我找不到 UID,我只是创建一个新用户并登录该用户。
从现在开始,移动设备向服务器发出的每个请求都将具有 SESSION(由 spring 安全性创建和附加)并且移动应用程序已通过身份验证
有人能告诉我这是不是一种好的做事方式吗? 我应该停止使用会话并切换到 Spring-Security-OAUTH2 吗?
编辑 1
根据 Dave 的建议,这里更新了 spring-安全配置:
<!- 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>
Facebook 已经在使用 OAuth2 服务器端,并为客户端提供了自己的原生 SDK,所以我看不出你在服务器端使用 OAuth2 有任何优势,除非你的用例超出了你的范围大纲如上。 Spring OAuth2 也有客户端支持,但不是在本机应用程序中,所以从原则上讲,我真的没有发现您的建议有任何问题。您没有详细说明您将在服务器中的何处设置安全上下文,我认为这可能是一个重要的细节——它必须发生在安全过滤器链中的正确位置才能使会话成为已更新。
我根据 Dave Syer 在这里的回答以及他放在一起的 Spring 安全性 Angular 材料尝试了类似的实现。要查看示例,请查看我的 forked github repo, specifically the classes in the security 包。