8

ellou 'Come posso autenticare l'utente in WebSocket 2.0 di Play?

Ho un metodo Play WebSocket comune che funziona come previsto, ma devo autenticare l'utente. Purtroppo quando si cerca anche modo più semplice per identificare utenti nel metodo:

public class Application extends Controller { 
    public static WebSocket<JsonNode> connect() { 
     return new WebSocket<JsonNode>() { 

      @Override 
      public void onReady(final WebSocket.In<JsonNode> in, final WebSocket.Out<JsonNode> out) { 
       User logged = User.findByUsername(Http.Context.current().request().username()); 
       // ... 
      } 
     }; 
    } 
} 

ottengo un errore:

java.lang.RuntimeException: There is no HTTP Context available from here. 

mia soluzione attuale è quella di passare a caso, identificatore univoco per visualizzare e salvarlo in modello User , che posso connettermi al socket dalla vista e trovare l'utente con l'identificatore dato, ma questo non è perfetto in quanto può esserci una sola connessione WebSocket per utente e inoltre non impedisce lo spoofing.

Come devo autenticare l'utente e prevenire attacchi di spoofing?

risposta

0

Poiché i dati che voglio inviare sono sensibili e in questo caso la sicurezza è più importante per me di prestazioni, alla fine ho usato messaggi in due passaggi, prima l'invio tramite ID WebSocket del messaggio e alcuni dati non importanti e quindi il recupero tramite AJAX e il corpo del messaggio di azione protetto dopo l'autenticazione dell'utente.

questione rimane aperta: Naturalmente se ci saranno altri suggerimenti farò cambiare il mio voto :)

1

Non so da dove viene il tuo pezzo di codice, ma dovresti essere in grado di accedere alla richiesta HTTP sull'inizializzazione del Websocket (prima connessione), cioè dovresti essere in grado di verificare l'autenticazione solo quando avvii la connessione socket WebSocket (la chiamata successiva non utilizzerà HTTP, è come funziona Webscokets).

Così, per esempio, nel controller, si potrebbe avere qualcosa di simile:

public class Application extends Controller { 

    public static WebSocket<JsonNode> connect() { 

     Logger.info("Username from request = " + request().username()); 

     return new WebSocket<JsonNode>() { 

      @Override 
      public void onReady(final WebSocket.In<JsonNode> in, final WebSocket.Out<JsonNode> out) { 
       // .... 

      } 

     }; 
    } 

} 
+0

Ho modificato il mio esempio, per adattarlo al vostro codice, come potete vedere l'ho inserito in 'onReady (...)', restituisce l'eccezione, quando posizionato prima di 'return' restituisce null. Ovviamente entrambe le righe (il tuo 'request(). Username()' e il mio 'Http.Context.current() ...') restituiscono un nome utente valido nell'azione comune. – biesior

+0

Non hai alcun tipo di annotazione sulle azioni comuni? Come stai impostando il nome utente? –

+0

Entrambe le azioni si trovano nello stesso controller, l'annotazione per Secured.class è inclusa nel controller, non all'azione, quindi entrambi dovrebbero utilizzarle allo stesso modo. Penso che il problema è che l'azione comune ottiene Http.Context e WebSocket non lo è. – biesior

1

Hai provato recuperare l'ID utente autenticato dalla sessione HTTP, invece? Il contesto sembra essere disponibile a quel punto.