2016-01-12 5 views
9

Ich habe in den letzten Tagen wirklich tief und tief gesucht, wie man das macht und habe mich schließlich dazu entschieden, sich geschlagen zu geben und bitte um Hilfe zu bitten !!!Spring Zuul API Gateway mit Spring Session/Redis Authentifizieren und Routen in derselben Anfrage

Ich habe Dr. Dave Syer Tutorial folgte auf Winkel- und Spring Security speziell die Zuul Proxy als api-Gateway und mit Spring Session mit 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)

Das Problem, das ich habe ist, dass ich Ressource Rest Dienstleistungen anzurufenden über das Gateway von einer externen Anwendung mit dem folgenden Header:

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); 

von der Ressource zuzuul und dann Zugriff hat auf die authentifizierte Sitzung über redis authentifiziert und dann weitergeleitet werden.

Das Problem besteht darin, dass die Sitzung anscheinend nur für das erneute Veröffentlichen im Gateway festgeschrieben wird, nachdem die Anforderung geantwortet hat. Was passiert, wenn ich einen Ressourcendienst mit dem Header anrufe, kann ich die erfolgreiche Authentifizierung im Gateway und in der Sitzung sehen, die erstellt wird, aber ich bekomme eine 403 in der Ressource, weil die Sitzung nicht in redis nach ist wurde über Zuul geroutet.

Allerdings, wenn ich den Fehler bekomme, greifen Sie die Session-ID und fügen Sie es in den Header und versuchen Sie es erneut funktioniert, da jetzt meine authentifizierte Sitzung für das Ressource-Projekt verfügbar ist, nachdem es geroutet wurde.

Könnte mir bitte jemand in die Richtung zeigen, wie ich meine Anrufe über das Gateway bekomme, um mich in derselben Anfrage zu authentifizieren und zu routen?

Dank Justin

+0

haben Sie es gelöst? Ich habe das gleiche Problem. –

Antwort

9

Ich folgte Justin Taylors Beiträge auf verschiedenen Seiten, so dass dies seine Lösung ist. Es macht mich Lösungscode mit Quelle hier zu haben, spüren:

  1. Make Spring Session begehen eifrig - seit dem Frühjahr-Sitzung v1.0 gibt Anmerkung Eigenschaft ist @EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) die sofort Sitzungsdaten in Redis speichert. Dokumentation here.
  2. Einfache Zuul Filter für Session in die aktuelle Anfrage des Header hinzugefügt:
@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; 
    } 

} 

Noch einmal - das ist nicht meine Lösung - Anmeldeinformationen Justin Taylor gehen.

+0

Cool stoked es war hilfreich! Ich hoffe, dass es eine bessere Integration mit Zuul und Spring Sessions in der Zukunft geben wird, die dafür sorgen werden, dass dies ein ziemlich Standard-Anwendungsfall für eine Edge-Architektur/Gateway mit zustandslosen Apis ist. –

+0

Für diejenigen, die darauf stolpern. Dieser Filter funktioniert grundsätzlich out of the box. Setzen Sie für die anderen Methoden den Typ auf "pre" und die Reihenfolge auf null. Nicht sicher, warum diese weggelassen werden, da sie im Wesentlichen eine Zeile sind, die diesen Code kopieren und einfügen. – Ceekay

+1

@Ceekay danke für deinen Kommentar. Ich habe den Code repariert. Dieser Code sollte nur ein Beispiel sein. Z.B. Es verarbeitet nicht mehrere Cookie-Werte (es überschreibt alle vorhandenen Werte mit SESSION = ). – shobull

3

ich über die verzögerte Antwort hier so traurig bin, einer der großen Vorteile von Südafrika ist unsere große Telekom-hehe, ich habe für eine Weile und meine Quellcode kein Internet zu Hause hatte für Das ist auf meinem Heim-PC.

Ja Steve ist auf dem richtigen Weg. Es gibt zwei Probleme, die Sie hier lösen werden müssen:

  1. Frühjahrssitzung verpflichtet nur die authentifizierte Sitzung auf Antwort auf die anfängliche eingehende Anfrage Redis. Der erste Schritt besteht also darin, dem Link zu folgen, den steve zur Verfügung stellt, um sicherzustellen, dass die Frühlingssession sich dazu verpflichtet, bei jeder Änderung der Sitzung erneut zu erscheinen.

  2. Zuul propagiert diese neu authentifizierte Sitzung nicht auf dem ursprünglichen Routing. Also, was Sie tun müssen, ist die Verwendung eines zuul Pre-Filters (viele Beispiele herum), die die authentifizierte Session-ID erhält und sie dann zu der Anfrage an die Ressource hinter dem Gateway hinzufügt. Sie sehen eine Setter-Methode für die zuul-Anfrage, um die Sitzungs-ID festzulegen.

Wenn Sie dies nicht tun, müssen Sie zwei Anrufe tun, ein authentifizieren und eine gültige Session-ID zu erhalten, die in redis von Frühjahrssitzung sein würde, und dann den nachfolgenden Aufruf mit Ihrer authentifizierte Sitzung Ich würde.

Ich kämpfte eine Weile mit diesem, aber als ich es funktionierte, war es genau richtig. Ich habe diese Lösung erweitert, um nicht nur für http Basic zu arbeiten, sondern in einer jwt-Token-Implementierung.

Hoffentlich hilft dies, sobald ich zu Hause verbunden bin kann ich die Quelle posten.

Viel Glück! Justin

Verwandte Themen