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- http
Tags konfigurieren , Rechte? Eine für / login mit UsernamePasswordAuthenticationFilter
und eine für REST-URLs mit benutzerdefinierten JwtAuthenticationFilter
.
Erstellt die Konfiguration von zwei http
Elementen zwei springSecurityFitlerChains
? Ist UsernamePasswordAuthenticationFilter
standardmäßig deaktiviert, bis ich deklariere form-login
? Wie ersetze ich durch SecurityContextPersistenceFilter
einen Filter, der Authentication
aus vorhandenen JWT-token
statt erhalten wird JSESSIONID
?
quelle
Antworten:
Die Federsicherheitsfilterkette ist ein sehr komplexer und flexibler Motor.
In der aktuellen Dokumentation zu Stable Release 4.2.1 , Abschnitt 13.3 Filterreihenfolge, sehen Sie die Filterorganisation der gesamten Filterkette:
Jetzt werde ich versuchen, Ihre Fragen einzeln zu beantworten:
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:
Dabei werden diese Filter im Filterketten-Proxy konfiguriert:
Hinweis: Ich erhalte sie, indem ich einen einfachen RestController erstelle, der den FilterChainProxy @Autowires verwendet und dessen Inhalt zurückgibt:
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:http
Dies 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:Jetzt sieht die filterChain folgendermaßen aus:
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:
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.).
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 ohnesecurity:"none"
Attribut erstellt wird.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.Nein, Sie sind nicht gezwungen, dies zu tun. Sie können beide
UsernamePasswordAuthenticationFilter
und dasJwtAuthenticationFilter
im 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.Ja das stimmt
Ja, Sie konnten es in den Filtern sehen, die in jeder der von mir geposteten Konfigurationen ausgelöst wurden
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:BEARBEITEN:
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.
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.
quelle
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)}
Nein,
UsernamePasswordAuthenticationFilter
erweitertAbstractAuthenticationProcessingFilter
, und dies enthält eineRequestMatcher
, dh Sie können Ihre eigene Verarbeitungs-URL definieren. Dieser Filter behandelt nur dieRequestMatcher
Übereinstimmungen mit der Anforderungs-URL. Die Standard-Verarbeitungs-URL ist/login
.Spätere Filter können die Anforderung weiterhin verarbeiten, wenn sie
UsernamePasswordAuthenticationFilter
ausgeführt wirdchain.doFilter(request, response);
.Weitere Details zu Core Fitlern
UsernamePasswordAuthenticationFilter
wird erstellt von<form-login>
, dies sind Standardfilter-Aliase und ReihenfolgeEs hängt davon ab, ob die Vor-Fitler erfolgreich sind, ist aber
FilterSecurityInterceptor
normalerweise der letzte Fitler.Ja, jede fitlerChain hat eine
RequestMatcher
, wenn dieRequestMatcher
mit der Anfrage übereinstimmt, wird die Anfrage von den Fitlern in der Fitler-Kette bearbeitet.Die Standardeinstellung
RequestMatcher
entspricht 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)
quelle
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
WebAsyncManagerIntegrationFilter
Bietet die Integration zwischen dem SecurityContext und dem WebAsyncManager von Spring Web.SecurityContextPersistenceFilter
Dieser 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 .
HeaderWriterFilter
Filtern Sie die Implementierung, um der aktuellen Antwort Header hinzuzufügen.LogoutFilter
Wenn die Anforderungs-URL/logout
(für die Standardkonfiguration) ist oder wenn die Anforderungs-URL-Mathematik inRequestMatcher
konfiguriertLogoutConfigurer
istLogoutConfigurer
/
oder Abmeldeerfolgs-URL um oder ruft den konfigurierten logoutSuccessHandler auf.UsernamePasswordAuthenticationFilter
HTTP POST
default)/login
oder Streichhölzer.loginProcessingUrl()
in konfiguriertFormLoginConfigurer
dannUsernamePasswordAuthenticationFilter
versucht Authentifizierung.usernameParameter(String)
,passwordParameter(String)
..loginPage()
überschreibt die StandardeinstellungenAuthentication
Objekt (UsernamePasswordAuthenticationToken
oder eine ImplementierungAuthentication
im Fall Ihres benutzerdefinierten Authentifizierungsfilters) wird erstellt.authenticationManager.authenticate(authToken)
wird aufgerufenAuthenticationProvider
Authentifizierungsmethoden konfigurieren können, die alle Authentifizierungsanbietersupports
testen 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 istAuthenticationException
.authenticationSuccessHandler
Wille, Umleitungen auf die Ziel - URL aufgerufen werden , konfiguriert (Standard/
)SecurityContextHolderAwareRequestFilter
, wenn Sie damit einen Spring Security-fähigen HttpServletRequestWrapper in Ihrem Servlet-Container installierenAnonymousAuthenticationFilter
Erkennt, ob im SecurityContextHolder kein Authentifizierungsobjekt vorhanden ist. Wenn kein Authentifizierungsobjekt gefunden wird, wirdAuthentication
object (AnonymousAuthenticationToken
) mit der erteilten Berechtigung erstelltROLE_ANONYMOUS
. Hier wirdAnonymousAuthenticationToken
das Identifizieren nicht authentifizierter Benutzer nachfolgender Anforderungen erleichtert.ExceptionTranslationFilter
, um Spring Security-Ausnahmen abzufangen, sodass entweder eine HTTP-Fehlerantwort zurückgegeben oder ein geeigneter AuthenticationEntryPoint gestartet werden kannFilterSecurityInterceptor
Es wird
FilterSecurityInterceptor
fast die letzte in der Filterkette geben, die das Authentifizierungsobjekt abruftSecurityContext
und 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 erlaubteAntMatchers
konfiguriert inHttpSecurityConfiguration
.Betrachten Sie die Ausnahmen 401-UnAuthorized und 403-Forbidden. Diese Entscheidungen werden zuletzt in der Filterkette getroffen
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.
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?
quelle