Servlet 3 Async-Unterstützung mit Spring MVC und Spring Security

Servlet 3 Async Support mit Spring MVC und Spring Security

1. Einführung

In diesem kurzen Tutorial konzentrieren wir uns aufthe Servlet 3 support for async requests, and how Spring MVC and Spring Security handle these.

Die grundlegendste Motivation für Asynchronität in Webanwendungen ist die Bearbeitung von Anfragen mit langer Laufzeit. In den meisten Anwendungsfällen müssen wir sicherstellen, dass das Spring Security-Prinzipal an diese Threads weitergegeben wird.

Und natürlich liegt Spring Securityintegrates with @Asyncaußerhalb des Bereichs von MVC und verarbeitet auch HTTP-Anforderungen.

2. Maven-Abhängigkeiten

Um die asynchrone Integration in Spring MVC verwenden zu können, müssen die folgenden Abhängigkeiten in unserepom.xml aufgenommen werden:


    org.springframework.security
    spring-security-web
    4.2.1.RELEASE


    org.springframework.security
    spring-security-config
    4.2.1.RELEASE

Die neueste Version der Spring Security-Abhängigkeiten finden Sie inhere.

3. Feder MVC und@Async

Gemäß den offiziellendocs integriert sich Spring Security inWebAsyncManager.

Der erste Schritt besteht darin, sicherzustellen, dass unserespringSecurityFilterChain für die Verarbeitung asynchroner Anforderungen eingerichtet sind. Wir können dies entweder in der Java-Konfiguration tun, indem wir der KonfigurationsklasseServletdie folgende Zeile hinzufügen:

dispatcher.setAsyncSupported(true);

oder in XML config:


    springSecurityFilterChain
    org.springframework.web.filter.DelegatingFilterProxy
    true


    springSecurityFilterChain
    /*
    REQUEST
    ASYNC

Wir müssen auch den Parameterasync-supported in unserer Servlet-Konfiguration aktivieren:


    ...
    true
    ...

Jetzt können wir asynchrone Anforderungen mitSecurityContext senden, die mit ihnen weitergegeben werden.

Interne Mechanismen in Spring Security stellen sicher, dass unsereSecurityContext nicht mehr gelöscht werden, wenn eine Antwort in weiterenThread festgeschrieben wird, was zu einer Benutzerabmeldung führt.

4. Anwendungsfälle

Lassen Sie uns dies anhand eines einfachen Beispiels in Aktion sehen:

@Override
public Callable checkIfPrincipalPropagated() {
    Object before
      = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    log.info("Before new thread: " + before);

    return new Callable() {
        public Boolean call() throws Exception {
            Object after
              = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            log.info("New thread: " + after);
            return before == after;
        }
    };
}

Wir wollen überprüfen, ob die FederSecurityContext an den neuen Thread weitergegeben wird.

Bei der oben vorgestellten Methode werdenCallable automatisch mit den enthaltenenSecurityContext ausgeführt, wie in den Protokollen dargestellt:

web - 2017-01-02 10:42:19,011 [http-nio-8081-exec-3] INFO
  o.example.web.service.AsyncService - Before new thread:
  [email protected]:
  Username: temporary; Password: [PROTECTED]; Enabled: true;
  AccountNonExpired: true; credentialsNonExpired: true;
  AccountNonLocked: true; Granted Authorities: ROLE_ADMIN

web - 2017-01-02 10:42:19,020 [MvcAsync1] INFO
  o.example.web.service.AsyncService - New thread:
  [email protected]:
  Username: temporary; Password: [PROTECTED]; Enabled: true;
  AccountNonExpired: true; credentialsNonExpired: true;
  AccountNonLocked: true; Granted Authorities: ROLE_ADMIN

Ohne dieSecurityContext einzurichten, die weitergegeben werden sollen, erhält die zweite Anforderung den Wertnull.

Es gibt auch andere wichtige Anwendungsfälle für die Verwendung asynchroner Anforderungen mit propagiertenSecurityContext:

  • Wir möchten mehrere externe Anforderungen erstellen, die parallel ausgeführt werden können und deren Ausführung möglicherweise viel Zeit in Anspruch nimmt

  • Wir müssen einige wichtige Vorgänge lokal ausführen, und unsere externe Anforderung kann parallel dazu ausgeführt werden

  • Andere stellen Feuer-und-Vergessen-Szenarien dar, wie zum Beispiel das Senden einer E-Mail

Beachten Sie, dass die Konvertierung dieser in einen asynchronen Ansatz möglicherweise Synchronisierungsergebnisse erfordert, wenn unsere mehreren Methodenaufrufe zuvor synchron miteinander verkettet waren.

5. Fazit

In diesem kurzen Tutorial haben wir die Spring-Unterstützung für die Verarbeitung asynchroner Anforderungen in einem authentifizierten Kontext. veranschaulicht

Aus Sicht des Programmiermodells erscheinen die neuen Funktionen täuschend einfach. Aber es gibt sicherlich einige Aspekte, die ein tieferes Verständnis erfordern.

Dieses Beispiel ist auch als Maven-Projektover on Github verfügbar.