2016-01-12 24 views
9

Ho cercato per molto tempo negli ultimi giorni su come farlo e ho finalmente deciso di ammettere la sconfitta e chiedere aiuto, per favore !!!Spring Zuul API Gateway con Spring Session/Redis Autentica e instradamento nella stessa richiesta

Ho seguito il tutorial di Dr Dave Syer su angolare e la sicurezza Primavera in particolare lo Zuul proxy come un gateway API e l'utilizzo di sessione primaverile con Redis (https://github.com/spring-guides/tut-spring-security-and-angular-js/tree/master/double#_sso_with_oauth2_angular_js_and_spring_security_part_v)

Il problema che sto avendo è che io chiamo i servizi delle risorse di riposo tramite il gateway da un'applicazione esterna con la seguente intestazione:

String plainCreds = "user:password"; 
byte[] plainCredsBytes = plainCreds.getBytes(); 
byte[] base64CredsBytes = Base64.getEncoder().encode(plainCredsBytes); 
String base64Creds = new String(base64CredsBytes); 

HttpHeaders headers = new HttpHeaders(); 
headers.add("Authorization", "Basic " + base64Creds); 

essere autenticata e poi instradato da Zuul e quindi la risorsa di avere accesso alla sessione autenticata tramite Redis.

Il problema è che la sessione sembra impegnarsi solo per i redis nel gateway dopo che la richiesta ha risposto. Quindi, quello che sta succedendo è che quando chiamo un servizio di risorse con l'intestazione, posso vedere l'autenticazione di successo che si verifica nel gateway e nella sessione che si sta creando, tuttavia ottengo un 403 nella risorsa a causa della sessione che non è in redis dopo il suo stato indirizzato via zuul.

Tuttavia, se ottengo l'errore, acquisisco l'id di sessione e lo aggiungo all'intestazione e riprovo perché ora la mia sessione autenticata è disponibile per il progetto di risorsa dopo il suo instradamento.

Per favore qualcuno mi può indirizzare nella direzione di come faccio a ricevere le mie chiamate tramite il gateway per autenticarsi e instradare nella stessa richiesta, per favore?

Grazie Justin

+0

lo hai risolto? Sono dello stesso problema –

risposta

9

Ho seguito i post di Justin Taylor su pagine diverse, quindi questa è la sua soluzione. Mi fa senso avere una soluzione con il codice sorgente qui:

  1. Fai sessione primaverile impegnano con entusiasmo - dalla primavera-sessione v1.0 non è di proprietà di annotazione @EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) che salva immediatamente i dati della sessione in Redis. Documentazione here.
  2. filtro Zuul semplice per l'aggiunta di sessione in colpo di testa di richiesta corrente:
@Component 
public class SessionSavingZuulPreFilter extends ZuulFilter { 

    @Autowired 
    private SessionRepository repository; 

    @Override 
    public String filterType() { 
     return "pre"; 
    } 

    @Override 
    public int filterOrder() { 
     return 0; 
    } 

    @Override 
    public Object run() { 
     RequestContext context = RequestContext.getCurrentContext(); 

     HttpSession httpSession = context.getRequest().getSession(); 
     Session session = repository.getSession(httpSession.getId()); 

     context.addZuulRequestHeader("Cookie", "SESSION=" + httpSession.getId()); 

     log.info("ZuulPreFilter session proxy: {}", session.getId()); 

     return null; 
    } 

} 

Ancora una volta - questa non è la mia soluzione - le credenziali vanno a Justin Taylor.

+0

Cool ha attirato è stato utile! Spero che ci sarà una migliore integrazione con Zuul e Spring Session in futuro, che ne terranno conto come un caso d'uso piuttosto standard per un'architettura/gateway edge con apis stateless. –

+0

Per quelli che inciampano su questo. Questo filtro funziona praticamente fuori dalla scatola. Per gli "altri metodi", imposta il tipo su "pre" e l'ordine su zero. Non sono sicuro del motivo per cui questi sono omessi in quanto sono essenzialmente una riga che rende questo codice copia e incolla. – Ceekay

+1

@Ceekay grazie per il tuo commento. Ho risolto il codice. Questo codice doveva essere solo un esempio. Per esempio. non gestisce più valori Cookie (sostituisce tutti i valori esistenti con SESSION = ). – shobull

3

Mi dispiace per il ritardo nella risposta qui, una delle grandi cose di Sud Africa è il nostro grande telecomunicazioni hehe, non ho avuto internet a casa per un po 'e il mio codice sorgente per questo è sul mio pc di casa.

Sì, Steve è sulla strada giusta. Ci sono due problemi che è necessario risolvere per essere qui:

  1. sessione primaverile impegna unicamente la sessione autenticata per Redis sulla risposta alla richiesta in arrivo iniziale. Quindi, il primo passo è seguire questo collegamento fornito per garantire che la sessione primaverile si impegni a redis ogni volta che la sessione cambia.

  2. Zuul non propaga questa sessione appena autenticata sul routing iniziale. Quindi quello che devi fare è usare un prefiltro zuul (un sacco di esempi in giro) che ottiene l'id di sessione autenticato e poi lo aggiunge alla richiesta zuul alla risorsa dietro il gateway. Vedrai un metodo setter sulla richiesta zuul per impostare l'id della sessione.

Se non si esegue questa operazione, è necessario fare due chiamate, una per l'autenticazione e ottenere un ID di sessione valida che sarebbe in Redis dalla sessione primaverile, e poi la chiamata successiva con la sessione autenticata id.

Ho combattuto con questo per un po ', ma quando ho funzionato era perfetto. Ho esteso questa soluzione non solo per http base, ma anche per l'implementazione di un token jwt.

Speriamo che questo aiuti, non appena sono connesso a casa, posso postare la fonte.

Buona fortuna! Justin