PHP-Editor Zimo ist hier, um die Frage zu beantworten, ob der Spring Security-Filter Sitzungsinformationen von Redis erhält. Spring Security ist ein leistungsstarkes Sicherheitsframework, das einen vollständigen Satz an Authentifizierungs- und Autorisierungsmechanismen bereitstellt. Standardmäßig verwendet Spring Security HttpSession, um Benutzersitzungsinformationen zu verwalten. Mit der Konfiguration können wir jedoch Sitzungsinformationen in einem externen Speicher wie Redis speichern. Dies hat den Vorteil, dass eine verteilte Sitzungsverwaltung realisiert und die Skalierbarkeit des Systems verbessert werden kann. Daher können Spring Security-Filter Sitzungsinformationen von Redis abrufen.
Ich versuche, Spring-Boot, Spring-Security und Spring-Session zu verwenden, um das Anmeldesystem zu implementieren, und verwende Redis als Sitzungsspeicher.
Meine Konfiguration:
@enablewebsecurity @enablemethodsecurity @configuration @requiredargsconstructor public class securityconfig { private final userdetailsservice detailsservice; @bean public passwordencoder passwordencoder() { return new bcryptpasswordencoder(); } @bean public authenticationprovider authenticationprovider(passwordencoder passwordencoder) { daoauthenticationprovider provider = new daoauthenticationprovider(); provider.setpasswordencoder(passwordencoder); provider.setuserdetailsservice(this.detailsservice); return provider; } @bean public authenticationmanager authenticationmanager(authenticationprovider authenticationprovider) { return new providermanager(authenticationprovider); } @bean public securityfilterchain filterchain(httpsecurity http) throws exception { return http .csrf().disable() .cors(customizer.withdefaults()) .authorizehttprequests(auth -> { auth.requestmatchers("/api/v1/auth/register/**", "/api/v1/auth/login").permitall(); auth.anyrequest().authenticated(); }) .sessionmanagement(sessionmanagement -> sessionmanagement .sessioncreationpolicy(if_required) // .sessionfixation(sessionmanagementconfigurer.sessionfixationconfigurer::newsession) // .maximumsessions(100000) // //.sessionregistry(sessionregistry()) ) //.exceptionhandling((ex) -> ex.authenticationentrypoint(this.authentrypoint)) .logout(out -> out .logouturl("/api/v1/auth/logout") .invalidatehttpsession(true) // invalidate all sessions after logout .deletecookies("jsessionid") .logoutsuccesshandler((request, response, authentication) -> securitycontextholder.clearcontext() ) ) .build(); } @bean public securitycontextrepository securitycontextrepository() { return new httpsessionsecuritycontextrepository(); } }
Mein Login-Controller:
@postmapping("/login") public void login(@requestbody loginform form, httpservletrequest request, httpservletresponse response) { string ip = httprequestutil.getip(request); string device = httprequestutil.getdevice(request); loginformwrapper loginformwrapper = new loginformwrapper(form.email(), form.password(), ip, device); authenticationservice.login(loginformwrapper, request, response); }
und Authentifizierungsdienst:
@override public void login(loginformwrapper form, httpservletrequest request, httpservletresponse response) { authentication authentication = authenticationmanager.authenticate(usernamepasswordauthenticationtoken.unauthenticated( form.email().trim(), form.password())); // create a new context securitycontext context = securitycontextholder.createemptycontext(); context.setauthentication(authentication); // update securitycontextholder and strategy this.securitycontextholderstrategy.setcontext(context); this.securitycontextrepository.savecontext(context, request, response); }
Wenn ich das richtig verstehe
this.securitycontextholderstrategy.setcontext(context);
Die Authentifizierung sollte im Speicher der Anwendung gespeichert werden, z. B. in einem threadlokalen Kontext
und
`this.securitycontextrepository.savecontext(context, request, response);`
Sitzungsinformationen sollten in Redis gespeichert werden.
Wenn ich mich jetzt anmelde, sehe ich, dass die Daten in Redis gespeichert wurden:
Wenn ich jedoch überprüfe, was meine Anmeldeanfrage zurückgibt, sehe ich Folgendes:
Völlig andere Sitzungs-ID.
Meine erste Frage ist: Warum stimmen diese IDs nicht überein? Woher weiß der Frühling, nach welchem Schlüssel er suchen muss?
Eine andere Frage ist: Welcher Filter, um Daten von Redis zu erhalten? Ich versuche, alle Filter in der Filterkette zu debuggen:
[org.springframework.security.web.session.DisableEncodeUrlFilter@2fedae96, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@4945cd1f, org.springframework.security.web.context.SecurityContextHolderFilter@72499396, org.springframework.security.web.header.HeaderWriterFilter@7048d039, org.springframework.web.filter.CorsFilter@2dbfcbe4, org.springframework.security.web.authentication.logout.LogoutFilter@5d5a77de, org.springframework.security.web.session.ConcurrentSessionFilter@1f8e1096, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@651bec9a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@76d4e1af, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@6f13ed1, org.springframework.security.web.session.SessionManagementFilter@642693c2, org.springframework.security.web.access.ExceptionTranslationFilter@2199e1a4, org.springframework.security.web.access.intercept.AuthorizationFilter@48c584c]
Aber es scheint irgendwie die Sitzungsinformationen aus der httpserletrequest zu lesen – wenn ich jedoch den Schlüssel aus Redis entferne, schlägt die Authentifizierung für den Endpunkt fehl, der ihn benötigt.
Habe ich etwas verpasst? Rufe ich die Sitzungsinformationen von Redis ab und speichere sie in httpservlerrequest
, bevor mein Fitler startet? Oder wie liest es Redis-Daten?
Danke für deine Hilfe.
Der Wert im Sitzungscookie ist Base64-codiert:
echo '3c048eae-9f73-4df5-a009-bdf802ae37ca' | openssl base64 m2mwndhlywutowy3my00zgy1lwewmdktymrmodayywuzn2nhcg==
echo 'M2MwNDhlYWUtOWY3My00ZGY1LWEwMDktYmRmODAyYWUzN2NhCg==' | openssl base64 -d 3c048eae-9f73-4df5-a009-bdf802ae37ca
Bei der Base64-Dekodierung stimmt die Sitzungs-ID des Cookies mit der in Redis gespeicherten Sitzungs-ID überein.
Wenn Sie es noch nicht gelesen haben, würde ich dieses Dokument empfehlen: https://www.php.cn/link/e27c71957d1e6c223e0d48a165da2ee1
Besonders der Abschnitt „Die Komponenten des Sitzungsmanagements verstehen“: https://www.php.cn/link/e27c71957d1e6c223e0d48a165da2ee1#understanding-session-management-components
Sie haben nicht erwähnt, welche Version von Spring Security Sie verwenden, aber ich vermute, dass Sie Spring Security 6 verwenden. In diesem Abschnitt gibt es einen solchen Satz im Zusammenhang mit der Sitzungsauthentifizierung:
Das obige ist der detaillierte Inhalt vonErhält der Spring-Security-Filter Sitzungsinformationen von Redis?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!