接受facebook登录我的REST API

Joh*_*y19 8 rest facebook token spring-security spring-security-oauth2

我有一个后端服务器(Java/Spring/Spring Security).目前,当移动应用程序用户登录时,他们只需提交用户名/密码,Spring Security就会创建一个会话,并使用JSESSIONID将其分配给请求.

我们现在还在移动应用程序"使用Facebook登录"上有一个按钮.以下是我对其如何运作的理解.

  1. 移动应用使用facebook SDK获取"access_token"
  2. 移动应用程序从facebook(名称,姓氏,电子邮件等)中检索USer个人资料
  3. 如果用户名是唯一的,则移动检查(针对MY服务器)
  4. 如果用户名是唯一的,请调用MY REST api,使用此类/ login/facebook POST over SSL并传递access_token,电子邮件,用户名等...)
  5. 然后我的服务器检查access_token是否有效

    GET graph.facebook.com/debug_token? input_token={token-to-inspect} &access_token={app-token-or-admin-token}

  6. 如果是,如果facebook返回的UID已存在于我的本地数据库中,我将用户签名如下:
SecurityContextHolder.getContext().setAuthentication(
                new UsernamePasswordAuthenticationToken(username, null, ROLE_USER));
Run Code Online (Sandbox Code Playgroud)
  1. 如果我找不到UID,我只需创建一个新用户并登录该用户.

  2. 从现在起,移动设备向服务器发出的每个请求都将具有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>
Run Code Online (Sandbox Code Playgroud)

Dav*_*yer 3

Facebook 已经在使用 OAuth2 服务器端,并为客户端提供了自己的本机 SDK,因此我认为在服务器中使用 OAuth2 没有任何优势,除非您的用例超出了上面概述的范围。Spring OAuth2 也有客户端支持,但不是在本机应用程序中,所以我真的不认为您的提案原则上有任何问题。您没有详细说明将在服务器中的何处设置安全上下文,我认为这可能是一个重要的细节 - 它必须发生在安全过滤器链中的正确位置才能使会话生效更新。