2015-01-02 10 views
5

Ho un server di backend (Java/Spring/Spring Security). Attualmente quando gli utenti dal login app mobile, si limitano a inviare il proprio nome utente/password e Spring Security crea una sessione e assegnarla alla richiesta con un JSESSIONID.Accetta login Facebook nella mia API REST

Ora avremmo anche un pulsante nell'app mobile "Accedi con Facebook". Ecco la mia comprensione di come funzionerà.

  1. mobile app utilizza Facebook SDK per ottenere un "access_token"
  2. Mobile App retrive Profilo Utente da facebook (nome, cognome, e-mail, ecc ..)
  3. controlli mobili (contro il mio server) se il nome utente è unico
  4. Se nome utente univoco, chiamare il mio API REST, con qualcosa di simile/login/Facebook Share su SSL e passando l'access_token, e-mail, nome utente ecc ...)
  5. mio server quindi controlla se l'access_token è valido

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

  6. Se sì, se l'UID restituito da Facebook è già presente nel mio database locale, ho signin l'utente come segue:
SecurityContextHolder.getContext().setAuthentication(
       new UsernamePasswordAuthenticationToken(username, null, ROLE_USER)); 
  1. Se non trovo l'UID, creo un nuovo utente e accedo all'utente.

  2. e da ora in poi ogni richiesta fatta al server dal cellulare avrà la SESSIONE (creato e fissato dalla sicurezza a molla) e l'applicazione mobile viene autenticato

Qualcuno potrebbe dirmi se questo è un buon modo di fare le cose? Devo smettere di usare le sessioni e passare a Spring-Security-OAUTH2?


EDIT 1

Sulla base di consigli Dave Ecco l'aggiornamento config primavera-sicurezza:

<!- 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> 
+0

Un filtro molla è implementato per questo scopo.Si prega di consultare il seguente link: "Autenticazione Primavera Filtro per apolidi REST endpoint che utilizzano Facebook Token per l'autenticazione" https://github.com/ozgengunay/FBSpringSocialRESTAuth – Ozgen

risposta

2

Facebook sta già utilizzando lato server OAuth2, e fornisce il proprio SDK nativo per clienti, quindi non vedo alcun vantaggio nel tuo caso di utilizzare OAuth2 sul tuo server, a meno che il tuo caso d'uso non si estenda oltre quanto sopra descritto. Spring OAuth2 supporta anche il lato client, ma non in un'app nativa, quindi in realtà non vedo nulla di sbagliato in linea di principio con la tua proposta. Non hai detto in alcun dettaglio dove avresti impostato il contesto di sicurezza nel tuo server, e penso che potrebbe essere un dettaglio importante - deve succedere nella catena dei filtri di sicurezza nel posto giusto per ottenere la sessione da aggiornato.

+0

Grazie per la risposta! Ho pensato che usare Oauth2 sarebbe stato più semplice per integrare il login di Facebook. Solo un'idea in cui avrei avuto la possibilità di effettuare la migrazione dalla sessione al token. Riguardo a dove autenticare l'utente, beh, questo è qualcosa che * * * non ero sicuro su dove collocarlo .. Potresti indicarmi più in dettaglio dove deve sedersi nei filtri? – Johny19

+0

Se fossi in te vedrei l'implementazione di 'UsernamePasswordAuthenticationFilter' e lo adatterò per gestire credenziali diverse (token fb invece di username/password). Puoi quindi aggiungere il filtro usando 'addFilterAfter' nella stessa posizione di' UsernamePasswordAuthenticationFilter'. –

+0

perfetto grazie! Questo è ciò che ho fatto: creare una classe che estenda UsernamePasswordAuthenticationFilter e sovrascriva il metodo "attemptAuthentication". Faccio qualche controllo di base e creo un oggetto di autenticazione con il token come principale. Ho quindi creato questo bean nella mia configurazione e l'ho passato in un nuovo authenticationProvider (che gestirà la verifica del token contattando gli strumenti del grafico di Facebook se tutto va bene autenticando l'utente). e infine ho creato un nuovo " Johny19

0

Ho iniziato a implementare qualcosa di simile sulla base della risposta di Dave Syer qui insieme ai materiali angolari Spring Security che ha messo insieme. Per vedere un esempio vedere il mio repository github forked, in particolare le classi nel pacchetto security.