Home> Java> body text

Does spring-security filter get session information from redis?

PHPz
Release: 2024-02-09 22:30:08
forward
407 people have browsed it

php editor Zimo is here to answer the question about whether the Spring Security filter obtains session information from Redis. Spring Security is a powerful security framework that provides a complete set of authentication and authorization mechanisms. By default, Spring Security uses HttpSession to manage user session information. However, with configuration, we can store session information in external storage such as Redis. The advantage of this is that it can realize distributed session management and improve the scalability of the system. Therefore, Spring Security filters can obtain session information from Redis.

Question content

I am trying to use spring-boot, spring-security and spring-session to implement the login system, and use redis as the storage of the session.

My configuration:

@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(); } }
Copy after login

My 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); }
Copy after login

and authentication service:

@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); }
Copy after login

If I understand correctly

this.securitycontextholderstrategy.setcontext(context);Authentication should be kept in the application's memory, e.g. in a threadlocal context

and

`this.securitycontextrepository.savecontext(context, request, response);`
Copy after login

Session information should be saved to redis.

Now when I log in I see the data has been saved to redis:

However, when inspecting what is returned by my login request, I see:

Completely different session id.

My first question is:Why don't these ids match? How does spring know which key to look for?

Another question is: what filter to get data from redis? I try to debug all filters in the filter chain:

[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]
Copy after login

But it seems to read the session information from the httpserletrequest somehow - however, if I remove the key from redis, the authentication fails for the endpoint that requires it.

Did I miss something? Do I retrieve the session information from redis and store it inhttpservlerrequestbefore my fitler starts? Or how does it read redis data?

thanks for your help.

Solution

The value in the session cookie is base64 encoded:

echo '3c048eae-9f73-4df5-a009-bdf802ae37ca' | openssl base64 m2mwndhlywutowy3my00zgy1lwewmdktymrmodayywuzn2nhcg==
Copy after login
echo 'M2MwNDhlYWUtOWY3My00ZGY1LWEwMDktYmRmODAyYWUzN2NhCg==' | openssl base64 -d 3c048eae-9f73-4df5-a009-bdf802ae37ca
Copy after login

So when base64 decoded, the session id of the cookie matches the session id stored in redis.

If you haven't read it yet, I would recommend this document://m.sbmmt.com/link/e27c71957d1e6c223e0d48a165da2ee1

Especially the "Understanding Components of Session Management" section://m.sbmmt.com/link/e27c71957d1e6c223e0d48a165da2ee1#understanding-session-management-components

You didn't mention which version of spring security you are using, but I'm guessing you are using spring security 6. In this section, there is such a sentence related to sessionauthentication:

The above is the detailed content of Does spring-security filter get session information from redis?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!