Funktionsweise der Spring Security Filterkette

135

Mir ist klar, dass die Spring-Sicherheit auf einer Filterkette aufbaut, die die Anforderung abfängt, die Authentifizierung erkennt (nicht), zum Authentifizierungseintrittspunkt umleitet oder die Anforderung an den Autorisierungsdienst weiterleitet und die Anforderung schließlich entweder das Servlet trifft oder eine Sicherheitsausnahme auslöst (nicht authentifiziert oder nicht autorisiert). DelegatingFitlerProxy klebt diese Filter zusammen. Um ihre Aufgaben auszuführen, filtern diese Zugriffsdienste wie UserDetailsService und AuthenticationManager .

Schlüsselfilter in der Kette sind (in der Reihenfolge)

  • SecurityContextPersistenceFilter (stellt die Authentifizierung von JSESSIONID wieder her)
  • UsernamePasswordAuthenticationFilter (führt die Authentifizierung durch)
  • ExceptionTranslationFilter (Sicherheitsausnahmen von FilterSecurityInterceptor abfangen)
  • FilterSecurityInterceptor (kann Authentifizierungs- und Autorisierungsausnahmen auslösen)

Ich bin verwirrt, wie diese Filter verwendet werden. Wird für den im Frühjahr bereitgestellten Formular-Login UsernamePasswordAuthenticationFilter nur für / login verwendet und letztere Filter nicht? Konfiguriert das Formularanmelde- Namespace-Element diese Filter automatisch? Erreicht jede Anforderung (authentifiziert oder nicht) FilterSecurityInterceptor für eine nicht angemeldete URL?

Was ist, wenn ich meine REST-API mit einem JWT-Token sichern möchte , das vom Login abgerufen wird? Ich muss zwei Namespace-Konfigurations- httpTags konfigurieren , Rechte? Eine für / login mit UsernamePasswordAuthenticationFilterund eine für REST-URLs mit benutzerdefinierten JwtAuthenticationFilter.

Erstellt die Konfiguration von zwei httpElementen zwei springSecurityFitlerChains? Ist UsernamePasswordAuthenticationFilterstandardmäßig deaktiviert, bis ich deklariere form-login? Wie ersetze ich durch SecurityContextPersistenceFiltereinen Filter, der Authenticationaus vorhandenen JWT-tokenstatt erhalten wird JSESSIONID?

Tuomas Toivonen
quelle
Die Standardreihenfolge der Filter ist in org.springframework.security.config.annotation.web.builders.FilterComparator
blacelle

Antworten:

210

Die Federsicherheitsfilterkette ist ein sehr komplexer und flexibler Motor.

Schlüsselfilter in der Kette sind (in der Reihenfolge)

  • SecurityContextPersistenceFilter (stellt die Authentifizierung von JSESSIONID wieder her)
  • UsernamePasswordAuthenticationFilter (führt die Authentifizierung durch)
  • ExceptionTranslationFilter (Sicherheitsausnahmen von FilterSecurityInterceptor abfangen)
  • FilterSecurityInterceptor (kann Authentifizierungs- und Autorisierungsausnahmen auslösen)

In der aktuellen Dokumentation zu Stable Release 4.2.1 , Abschnitt 13.3 Filterreihenfolge, sehen Sie die Filterorganisation der gesamten Filterkette:

13.3 Filterbestellung

Die Reihenfolge, in der Filter in der Kette definiert werden, ist sehr wichtig. Unabhängig davon, welche Filter Sie tatsächlich verwenden, sollte die Reihenfolge wie folgt lauten:

  1. ChannelProcessingFilter , da möglicherweise eine Umleitung zu einem anderen Protokoll erforderlich ist

  2. SecurityContextPersistenceFilter , sodass zu Beginn einer Webanforderung ein SecurityContext im SecurityContextHolder eingerichtet werden kann und alle Änderungen am SecurityContext nach Beendigung der Webanforderung in die HttpSession kopiert werden können (zur Verwendung mit der nächsten Webanforderung bereit).

  3. ConcurrentSessionFilter , da es die SecurityContextHolder-Funktionalität verwendet und die SessionRegistry aktualisieren muss, um laufende Anforderungen des Principals widerzuspiegeln

  4. Authentifizierungsverarbeitungsmechanismen - UsernamePasswordAuthenticationFilter , CasAuthenticationFilter , BasicAuthenticationFilter usw. - damit der SecurityContextHolder so geändert werden kann, dass er ein gültiges Authentifizierungsanforderungstoken enthält

  5. Der SecurityContextHolderAwareRequestFilter , wenn Sie ihn verwenden, um einen Spring Security-fähigen HttpServletRequestWrapper in Ihrem Servlet-Container zu installieren

  6. Der JaasApiIntegrationFilter , wenn sich ein JaasAuthenticationToken im SecurityContextHolder befindet, verarbeitet die FilterChain als Betreff im JaasAuthenticationToken

  7. RememberMeAuthenticationFilter . Wenn also kein früherer Authentifizierungsverarbeitungsmechanismus den SecurityContextHolder aktualisiert hat und die Anforderung ein Cookie enthält, mit dem Remember-Me-Dienste ausgeführt werden können, wird dort ein geeignetes gespeichertes Authentifizierungsobjekt abgelegt

  8. AnonymousAuthenticationFilter , sodass ein anonymer Authentifizierungsobjekt dort abgelegt wird, wenn kein früherer Authentifizierungsverarbeitungsmechanismus den SecurityContextHolder aktualisiert hat

  9. ExceptionTranslationFilter , um alle Spring Security-Ausnahmen abzufangen, sodass entweder eine HTTP-Fehlerantwort zurückgegeben oder ein geeigneter AuthenticationEntryPoint gestartet werden kann

  10. FilterSecurityInterceptor , um Web-URIs zu schützen und Ausnahmen auszulösen , wenn der Zugriff verweigert wird

Jetzt werde ich versuchen, Ihre Fragen einzeln zu beantworten:

Ich bin verwirrt, wie diese Filter verwendet werden. Wird für den im Frühjahr bereitgestellten Formular-Login UsernamePasswordAuthenticationFilter nur für / login verwendet und letztere Filter nicht? Konfiguriert das Formularanmelde-Namespace-Element diese Filter automatisch? Erreicht jede Anforderung (authentifiziert oder nicht) FilterSecurityInterceptor für eine nicht angemeldete URL?

Sobald Sie einen <security-http>Abschnitt konfiguriert haben , müssen Sie für jeden Abschnitt mindestens einen Authentifizierungsmechanismus bereitstellen. Dies muss einer der Filter sein, die mit Gruppe 4 im Abschnitt 13.3 Filterreihenfolge aus der Spring Security-Dokumentation übereinstimmen, auf die ich gerade verwiesen habe.

Dies ist das minimal gültige Sicherheitselement: http, das konfiguriert werden kann:

<security:http authentication-manager-ref="mainAuthenticationManager" 
               entry-point-ref="serviceAccessDeniedHandler">
    <security:intercept-url pattern="/sectest/zone1/**" access="hasRole('ROLE_ADMIN')"/>
</security:http>

Dabei werden diese Filter im Filterketten-Proxy konfiguriert:

{
        "1": "org.springframework.security.web.context.SecurityContextPersistenceFilter",
        "2": "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter",
        "3": "org.springframework.security.web.header.HeaderWriterFilter",
        "4": "org.springframework.security.web.csrf.CsrfFilter",
        "5": "org.springframework.security.web.savedrequest.RequestCacheAwareFilter",
        "6": "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter",
        "7": "org.springframework.security.web.authentication.AnonymousAuthenticationFilter",
        "8": "org.springframework.security.web.session.SessionManagementFilter",
        "9": "org.springframework.security.web.access.ExceptionTranslationFilter",
        "10": "org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
    }

Hinweis: Ich erhalte sie, indem ich einen einfachen RestController erstelle, der den FilterChainProxy @Autowires verwendet und dessen Inhalt zurückgibt:

    @Autowired
    private FilterChainProxy filterChainProxy;

    @Override
    @RequestMapping("/filterChain")
    public @ResponseBody Map<Integer, Map<Integer, String>> getSecurityFilterChainProxy(){
        return this.getSecurityFilterChainProxy();
    }

    public Map<Integer, Map<Integer, String>> getSecurityFilterChainProxy(){
        Map<Integer, Map<Integer, String>> filterChains= new HashMap<Integer, Map<Integer, String>>();
        int i = 1;
        for(SecurityFilterChain secfc :  this.filterChainProxy.getFilterChains()){
            //filters.put(i++, secfc.getClass().getName());
            Map<Integer, String> filters = new HashMap<Integer, String>();
            int j = 1;
            for(Filter filter : secfc.getFilters()){
                filters.put(j++, filter.getClass().getName());
            }
            filterChains.put(i++, filters);
        }
        return filterChains;
    }

Hier konnten wir sehen, dass nur durch Deklarieren des <security:http>Elements mit einer Mindestkonfiguration alle Standardfilter enthalten sind, aber keiner von ihnen vom Authentifizierungstyp ist (4. Gruppe im Abschnitt 13.3 Filterreihenfolge). security:httpDies bedeutet also, dass nur durch Deklarieren des Elements der SecurityContextPersistenceFilter, der ExceptionTranslationFilter und der FilterSecurityInterceptor automatisch konfiguriert werden.

Tatsächlich sollte ein Authentifizierungsverarbeitungsmechanismus konfiguriert werden, und sogar Sicherheits-Namespace-Beans, die Ansprüche dafür verarbeiten, werfen beim Start einen Fehler aus, der jedoch umgangen werden kann, indem ein Einstiegspunkt-Referenzattribut hinzugefügt wird <http:security>

Wenn ich <form-login>der Konfiguration ein Basic hinzufüge , gehen Sie folgendermaßen vor:

<security:http authentication-manager-ref="mainAuthenticationManager">
    <security:intercept-url pattern="/sectest/zone1/**" access="hasRole('ROLE_ADMIN')"/>
    <security:form-login />
</security:http>

Jetzt sieht die filterChain folgendermaßen aus:

{
        "1": "org.springframework.security.web.context.SecurityContextPersistenceFilter",
        "2": "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter",
        "3": "org.springframework.security.web.header.HeaderWriterFilter",
        "4": "org.springframework.security.web.csrf.CsrfFilter",
        "5": "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter",
        "6": "org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter",
        "7": "org.springframework.security.web.savedrequest.RequestCacheAwareFilter",
        "8": "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter",
        "9": "org.springframework.security.web.authentication.AnonymousAuthenticationFilter",
        "10": "org.springframework.security.web.session.SessionManagementFilter",
        "11": "org.springframework.security.web.access.ExceptionTranslationFilter",
        "12": "org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
    }

Diese beiden Filter org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter und org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter werden nun in FilterChainProxy erstellt und konfiguriert.

Nun also die Fragen:

Wird für den im Frühjahr bereitgestellten Formular-Login UsernamePasswordAuthenticationFilter nur für / login verwendet und letztere Filter nicht?

Ja, es wird verwendet, um zu versuchen, einen Anmeldeverarbeitungsmechanismus abzuschließen, falls die Anforderung mit der URL UsernamePasswordAuthenticationFilter übereinstimmt. Diese URL kann so konfiguriert oder sogar geändert werden, dass sie jeder Anforderung entspricht.

Möglicherweise können auch mehrere Authentifizierungsverarbeitungsmechanismen in derselben FilterchainProxy konfiguriert sein (z. B. HttpBasic, CAS usw.).

Konfiguriert das Formularanmelde-Namespace-Element diese Filter automatisch?

Nein, das Formularanmeldeelement konfiguriert den UsernamePasswordAUthenticationFilter. Falls Sie keine Anmeldeseiten-URL angeben, konfiguriert es auch den org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter, der mit einer einfachen automatisch generierten Anmeldung endet Seite.

Die anderen Filter werden standardmäßig automatisch konfiguriert, indem nur ein <security:http>Element ohne security:"none"Attribut erstellt wird.

Erreicht jede Anforderung (authentifiziert oder nicht) FilterSecurityInterceptor für eine nicht angemeldete URL?

Jede Anfrage sollte sie erreichen, da es das Element ist, das dafür sorgt, ob die Anfrage die Rechte hat, die angeforderte URL zu erreichen. Einige der zuvor verarbeiteten Filter stoppen jedoch möglicherweise die Filterkettenverarbeitung und rufen einfach nicht auf FilterChain.doFilter(request, response);. Beispielsweise kann ein CSRF-Filter die Filterkettenverarbeitung stoppen, wenn die Anforderung nicht den Parameter csrf enthält.

Was ist, wenn ich meine REST-API mit einem JWT-Token sichern möchte, das vom Login abgerufen wird? Ich muss zwei Namespace-Konfigurations-http-Tags konfigurieren, Rechte? Andere für / login mit UsernamePasswordAuthenticationFilterund eine andere für REST-URLs mit benutzerdefinierten JwtAuthenticationFilter.

Nein, Sie sind nicht gezwungen, dies zu tun. Sie können beide UsernamePasswordAuthenticationFilterund das JwtAuthenticationFilterim selben http-Element deklarieren , dies hängt jedoch vom konkreten Verhalten jedes dieser Filter ab. Beide Ansätze sind möglich, und welcher letztendlich gewählt werden kann, hängt von den eigenen Vorlieben ab.

Erstellt das Konfigurieren von zwei http-Elementen zwei springSecurityFitlerChains?

Ja das stimmt

Ist UsernamePasswordAuthenticationFilter standardmäßig deaktiviert, bis ich die Formularanmeldung deklariere?

Ja, Sie konnten es in den Filtern sehen, die in jeder der von mir geposteten Konfigurationen ausgelöst wurden

Wie ersetze ich SecurityContextPersistenceFilter durch einen, der die Authentifizierung von einem vorhandenen JWT-Token anstelle von JSESSIONID erhält?

Sie können SecurityContextPersistenceFilter vermeiden, indem Sie nur die Sitzungsstrategie in konfigurieren <http:element>. Einfach so konfigurieren:

<security:http create-session="stateless" >

In diesem Fall können Sie es auch mit einem anderen Filter überschreiben, und zwar auf diese Weise innerhalb des <security:http>Elements:

<security:http ...>  
   <security:custom-filter ref="myCustomFilter" position="SECURITY_CONTEXT_FILTER"/>    
</security:http>
<beans:bean id="myCustomFilter" class="com.xyz.myFilter" />

BEARBEITEN:

Eine Frage zu "Sie könnten auch mehr als einen Authentifizierungsverarbeitungsmechanismus in derselben FilterchainProxy konfigurieren lassen". Überschreibt letzterer die von der ersten durchgeführte Authentifizierung, wenn mehrere Authentifizierungsfilter (Spring-Implementierung) deklariert werden? Wie hängt dies mit mehreren Authentifizierungsanbietern zusammen?

Dies hängt letztendlich von der Implementierung jedes Filters selbst ab, aber es ist wahr, dass die letzteren Authentifizierungsfilter zumindest jede vorherige Authentifizierung überschreiben können, die eventuell von vorhergehenden Filtern vorgenommen wurde.

Dies wird aber nicht unbedingt passieren. Ich habe einige Produktionsfälle in gesicherten REST-Diensten, in denen ich eine Art Autorisierungstoken verwende, das sowohl als HTTP-Header als auch innerhalb des Anforderungshauptteils bereitgestellt werden kann. Daher konfiguriere ich zwei Filter, die dieses Token wiederherstellen, in einem Fall aus dem HTTP-Header und dem anderen aus dem Anforderungshauptteil der eigenen Restanforderung. Es ist wahr, dass beide Filter versuchen, den Authentifizierungsmechanismus auszuführen, der ihn an den Manager delegiert, wenn eine http-Anforderung dieses Authentifizierungstoken sowohl als HTTP-Header als auch innerhalb des Anforderungshauptteils bereitstellt. Es könnte jedoch leicht vermieden werden, einfach zu überprüfen, ob die Anforderung vorliegt bereits zu Beginn der doFilter()Methode jedes Filters authentifiziert .

Wenn Sie mehr als einen Authentifizierungsfilter haben, müssen Sie mehr als einen Authentifizierungsanbieter haben, aber erzwingen Sie dies nicht. In dem Fall, den ich zuvor verfügbar gemacht habe, habe ich zwei Authentifizierungsfilter, aber nur einen Authentifizierungsanbieter, da beide Filter denselben Typ von Authentifizierungsobjekt erstellen, sodass der Authentifizierungsmanager ihn in beiden Fällen an denselben Anbieter delegiert.

Im Gegensatz dazu habe auch ich ein Szenario, in dem ich nur einen UsernamePasswordAuthenticationFilter veröffentliche, aber die Benutzeranmeldeinformationen können beide in DB oder LDAP enthalten sein, sodass ich zwei unterstützende UsernamePasswordAuthenticationToken-Anbieter habe und der AuthenticationManager jeden Authentifizierungsversuch vom Filter an die Anbieter delegiert nacheinander, um die Anmeldeinformationen zu überprüfen.

Ich denke, es ist klar, dass weder die Anzahl der Authentifizierungsfilter die Anzahl der Authentifizierungsanbieter noch die Anzahl der Anbieter die Anzahl der Filter bestimmt.

In der Dokumentation heißt es außerdem, dass SecurityContextPersistenceFilter für die Bereinigung des SecurityContext verantwortlich ist, was aufgrund des Thread-Poolings wichtig ist. Wenn ich es weglasse oder eine benutzerdefinierte Implementierung bereitstelle, muss ich die Reinigung manuell implementieren, oder? Gibt es ähnliche Fallstricke beim Anpassen der Kette?

Ich habe diesen Filter vorher nicht genau untersucht, aber nach Ihrer letzten Frage habe ich die Implementierung überprüft, und wie im Frühjahr üblich konnte fast alles konfiguriert, erweitert oder überschrieben werden.

Der SecurityContextPersistenceFilter delegiert in einer SecurityContextRepository- Implementierung die Suche nach dem SecurityContext. Standardmäßig wird ein HttpSessionSecurityContextRepository verwendet. Dies kann jedoch mithilfe eines der Konstruktoren des Filters geändert werden. Daher ist es möglicherweise besser, ein SecurityContextRepository zu schreiben, das Ihren Anforderungen entspricht, und es einfach im SecurityContextPersistenceFilter zu konfigurieren, wobei Sie auf das bewährte Verhalten vertrauen, anstatt alles von Grund auf neu zu erstellen.

jlumietu
quelle
3
Dies war eine aufschlussreiche Erklärung. Eine Frage zu "Sie könnten auch mehr als einen Authentifizierungsverarbeitungsmechanismus in derselben FilterchainProxy konfigurieren lassen". Überschreibt letzterer die von der ersten durchgeführte Authentifizierung, wenn mehrere Authentifizierungsfilter (Spring-Implementierung) deklariert werden? Wie hängt dies mit mehreren Authentifizierungsanbietern zusammen?
Tuomas Toivonen
In der Dokumentation heißt es außerdem, dass SecurityContextPersistenceFilter für die Bereinigung des SecurityContext verantwortlich ist, was aufgrund des Thread-Poolings wichtig ist. Wenn ich es weglasse oder eine benutzerdefinierte Implementierung bereitstelle, muss ich die Reinigung manuell implementieren, oder? Gibt es ähnliche Fallstricke beim Anpassen der Kette?
Tuomas Toivonen
1
@ TuomasToivonen Ich habe meine Antwort nach den Fragen in Ihren letzten Kommentaren
bearbeitet
1
@jlumietu In der Java-Annotation neben ("/ filterChain) fehlt ein Zitat . Auch wo platzieren Sie diese Methode? Ich habe versucht, sie in einen Controller einzufügen, und ich habe:No qualifying bean of type 'org.springframework.security.web.FilterChainProxy' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Dimitri Kopriwa
@BigDong Stellen Sie sicher, dass Sie SpringSecurityFilterChain sowohl in der web.xml- oder Java-Webapp-Konfiguration als auch in Ihrer Spring-Konfiguration deklariert haben. Dieses Code-Snippet muss genau wie Sie in einem Controller enthalten sein. Und ja, Sie sind Wright über das fehlende Zitat
jlumietu
4

UsernamePasswordAuthenticationFilterwird nur für verwendet /loginund letztere Filter nicht?

Nein, UsernamePasswordAuthenticationFiltererweitert AbstractAuthenticationProcessingFilter, und dies enthält eine RequestMatcher, dh Sie können Ihre eigene Verarbeitungs-URL definieren. Dieser Filter behandelt nur die RequestMatcherÜbereinstimmungen mit der Anforderungs-URL. Die Standard-Verarbeitungs-URL ist /login.

Spätere Filter können die Anforderung weiterhin verarbeiten, wenn sie UsernamePasswordAuthenticationFilterausgeführt wird chain.doFilter(request, response);.

Weitere Details zu Core Fitlern

Konfiguriert das Formularanmelde-Namespace-Element diese Filter automatisch?

UsernamePasswordAuthenticationFilterwird erstellt von <form-login>, dies sind Standardfilter-Aliase und Reihenfolge

Erreicht jede Anforderung (authentifiziert oder nicht) FilterSecurityInterceptor für eine nicht angemeldete URL?

Es hängt davon ab, ob die Vor-Fitler erfolgreich sind, ist aber FilterSecurityInterceptornormalerweise der letzte Fitler.

Erstellt das Konfigurieren von zwei http-Elementen zwei springSecurityFitlerChains?

Ja, jede fitlerChain hat eine RequestMatcher, wenn die RequestMatchermit der Anfrage übereinstimmt, wird die Anfrage von den Fitlern in der Fitler-Kette bearbeitet.

Die Standardeinstellung RequestMatcherentspricht allen Anforderungen, wenn Sie das Muster nicht konfigurieren oder die spezifische URL ( <http pattern="/rest/**") konfigurieren können .

Wenn Sie mehr über die Monteure erfahren möchten, können Sie den Quellcode in der Frühjahrssicherheit überprüfen. doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)

Chaoluo
quelle
4

Spring Security ist ein filterbasiertes Framework, das vor Ihrer Anwendung eine WALL (HttpFireWall) in Bezug auf Proxy-Filter oder Spring Managed Beans erstellt. Ihre Anfrage muss mehrere Filter durchlaufen, um Ihre API zu erreichen.

Ausführungsreihenfolge in Spring Security

  1. WebAsyncManagerIntegrationFilter Bietet die Integration zwischen dem SecurityContext und dem WebAsyncManager von Spring Web.

  2. SecurityContextPersistenceFilterDieser Filter wird nur einmal pro Anforderung ausgeführt. Füllt den SecurityContextHolder mit Informationen, die vor der Anforderung aus dem konfigurierten SecurityContextRepository abgerufen wurden, und speichert sie wieder im Repository, sobald die Anforderung abgeschlossen ist, und löscht den Kontextinhaber.
    Die Anforderung wird auf vorhandene Sitzung überprüft. Bei einer neuen Anfrage wird SecurityContext erstellt. Wenn die Anfrage eine Sitzung hat, wird der vorhandene Sicherheitskontext aus dem Repository abgerufen .

  3. HeaderWriterFilter Filtern Sie die Implementierung, um der aktuellen Antwort Header hinzuzufügen.

  4. LogoutFilterWenn die Anforderungs-URL /logout(für die Standardkonfiguration) ist oder wenn die Anforderungs-URL-Mathematik in RequestMatcherkonfiguriert LogoutConfigurerist

    • löscht den Sicherheitskontext.
    • macht die Sitzung ungültig
    • löscht alle Cookies mit den in konfigurierten Cookie-Namen LogoutConfigurer
    • Leitet zur standardmäßigen Abmeldeerfolgs-URL /oder Abmeldeerfolgs-URL um oder ruft den konfigurierten logoutSuccessHandler auf.
  5. UsernamePasswordAuthenticationFilter

    • Für jede andere Anforderungs-URL als loginProcessingUrl wird dieser Filter nicht weiter verarbeitet, sondern die Filterkette wird einfach fortgesetzt.
    • Wenn die angeforderte URL übereinstimmt ist (muss HTTP POSTdefault) /loginoder Streichhölzer .loginProcessingUrl()in konfiguriert FormLoginConfigurerdann UsernamePasswordAuthenticationFilterversucht Authentifizierung.
    • Die Standardparameter für das Anmeldeformular sind Benutzername und Passwort. Sie können überschrieben werden durch usernameParameter(String), passwordParameter(String).
    • Die Einstellung .loginPage() überschreibt die Standardeinstellungen
    • Beim Versuch der Authentifizierung
      • Ein AuthenticationObjekt ( UsernamePasswordAuthenticationTokenoder eine Implementierung Authenticationim Fall Ihres benutzerdefinierten Authentifizierungsfilters) wird erstellt.
      • und authenticationManager.authenticate(authToken)wird aufgerufen
      • Beachten Sie, dass wir eine beliebige Anzahl von AuthenticationProviderAuthentifizierungsmethoden konfigurieren können, die alle Authentifizierungsanbieter supportstesten und alle AuthToken / Authentifizierungsobjekte des Authentifizierungsanbieters überprüfen. Der unterstützende Authentifizierungsanbieter wird zur Authentifizierung verwendet. und gibt das Authentifizierungsobjekt zurück, falls die Authentifizierung erfolgreich ist AuthenticationException.
    • Wenn die Authentifizierung erfolgreich Sitzung erstellt und authenticationSuccessHandlerWille, Umleitungen auf die Ziel - URL aufgerufen werden , konfiguriert (Standard /)
    • Wenn die Authentifizierung fehlgeschlagen ist, wird der Benutzer zum nicht authentifizierten Benutzer und die Kette wird fortgesetzt.
  6. SecurityContextHolderAwareRequestFilter, wenn Sie damit einen Spring Security-fähigen HttpServletRequestWrapper in Ihrem Servlet-Container installieren

  7. AnonymousAuthenticationFilterErkennt, ob im SecurityContextHolder kein Authentifizierungsobjekt vorhanden ist. Wenn kein Authentifizierungsobjekt gefunden wird, wird Authenticationobject ( AnonymousAuthenticationToken) mit der erteilten Berechtigung erstellt ROLE_ANONYMOUS. Hier wird AnonymousAuthenticationTokendas Identifizieren nicht authentifizierter Benutzer nachfolgender Anforderungen erleichtert.

Debug-Protokolle
DEBUG - /app/admin/app-config at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
DEBUG - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@aeef7b36: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' 
  1. ExceptionTranslationFilter, um Spring Security-Ausnahmen abzufangen, sodass entweder eine HTTP-Fehlerantwort zurückgegeben oder ein geeigneter AuthenticationEntryPoint gestartet werden kann

  2. FilterSecurityInterceptor
    Es wird FilterSecurityInterceptorfast die letzte in der Filterkette geben, die das Authentifizierungsobjekt abruft SecurityContextund die Berechtigungsliste (Rollen erteilt) erhält, und es wird eine Entscheidung getroffen, ob diese Anforderung die angeforderte Ressource erreichen darf oder nicht. Die Entscheidung wird durch Abgleich mit getroffen die erlaubte AntMatcherskonfiguriert in HttpSecurityConfiguration.

Betrachten Sie die Ausnahmen 401-UnAuthorized und 403-Forbidden. Diese Entscheidungen werden zuletzt in der Filterkette getroffen

  • Nicht authentifizierter Benutzer, der versucht, auf öffentliche Ressourcen zuzugreifen - Zulässig
  • Nicht authentifizierter Benutzer, der versucht, auf gesicherte Ressourcen zuzugreifen - 401-UnAuthorized
  • Authentifizierter Benutzer, der versucht, auf eingeschränkte Ressourcen zuzugreifen (für seine Rolle eingeschränkt) - 403-Verboten

Hinweis: Benutzeranforderung fließt nicht nur in oben genannten Filter, aber es gibt andere Filter auch hier nicht dargestellt (. ConcurrentSessionFilter, RequestCacheAwareFilter, SessionManagementFilter...)
Es wird anders sein , wenn Sie Ihre benutzerdefinierte Auth Filter statt verwenden UsernamePasswordAuthenticationFilter.
Wenn Sie den JWT-Authentifizierungsfilter konfigurieren und weglassen .formLogin() i.e, UsernamePasswordAuthenticationFilter, wird dies anders.


Nur als Referenz. Filter in Spring-Web und Spring-Security
Hinweis: Siehe Paketname in Bild , da es einige andere Filter von orm und meinem benutzerdefinierten implementierten Filter gibt.

Geben Sie hier die Bildbeschreibung ein

Aus der Dokumentation wird die Reihenfolge der Filter wie folgt angegeben

  • ChannelProcessingFilter
  • ConcurrentSessionFilter
  • SecurityContextPersistenceFilter
  • LogoutFilter
  • X509AuthenticationFilter
  • AbstractPreAuthenticatedProcessingFilter
  • CasAuthenticationFilter
  • BenutzernamePasswordAuthenticationFilter
  • ConcurrentSessionFilter
  • OpenIDAuthenticationFilter
  • DefaultLoginPageGeneratingFilter
  • DefaultLogoutPageGeneratingFilter
  • ConcurrentSessionFilter
  • DigestAuthenticationFilter
  • BearerTokenAuthenticationFilter
  • BasicAuthenticationFilter
  • RequestCacheAwareFilter
  • SecurityContextHolderAwareRequestFilter
  • JaasApiIntegrationFilter
  • RememberMeAuthenticationFilter
  • AnonymousAuthenticationFilter
  • SessionManagementFilter
  • ExceptionTranslationFilter
  • FilterSecurityInterceptor
  • SwitchUserFilter

Sie können auch
die gängigste Methode zur Authentifizierung einer modernen Web-App verwenden?
Unterschied zwischen Authentifizierung und Autorisierung im Kontext von Spring Security?

PraveenKumar Lalasangi
quelle