Home > Back-end >  Java Spring cannot logout properly
Java Spring cannot logout properly

Time:02-06

I understand this question has been asked before, but none of what worked for the others worked for me. That said, here it is:

After setting up .logout() and its relevant associate methods, I still cannot make my Spring server logout properly. To be precise, this is the sequence I'm following:

  1. POST login, get token
  2. Use token for other HTTP requests, such as a standard GET for DB data
  3. Logout using the vanilla logout URL
  4. Try to do step 2 again, to see if logout was successful. At 4, for a reason that is unknown to me, I'm still able to GET the data, which is wrong.

Some of the things I've tried are:

  • .clearAuthentication(true).invalidateHttpSession(true)
  • Setting up the following bean on my SecurityConfig:
    @Bean
    public static ServletListenerRegistrationBean httpSessionEventPublisher() {
        return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
    }

None of it worked. Below are my security configurations. Any clues and help is much appreciated, and I thank you in advance.

SecurityConfig.java

@Configuration
public class SecurityConfig {

    @Autowired
    private AuthenticationManager authenticationManager;
    private final AuthSuccessHandler authSuccessHandler;
    private final JwtUserDetailsService jwtUserDetailsService;
    private final String secret;

    SecurityConfig(AuthSuccessHandler authSuccessHandler, JwtUserDetailsService jwtUserDetailsService, @Value("${jwt.secret}") String secret) {
        this.authSuccessHandler = authSuccessHandler;
        this.jwtUserDetailsService = jwtUserDetailsService;
        this.secret = secret;
    }

    @Bean
    public static ServletListenerRegistrationBean httpSessionEventPublisher() {
        return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .csrf()
                .disable()
                .authorizeHttpRequests((auth) -> {
                    try {
                        auth
                                .requestMatchers("/user").hasRole("USER")
                                .requestMatchers("/admin").hasRole("ADMIN")
                                .requestMatchers("**/encoding-results/**", "**/encoding-results").hasAnyRole("ADMIN")
                                .requestMatchers("**/video/**").hasAnyRole("ADMIN")
                                .requestMatchers("**/codec/**").hasAnyRole("ADMIN")
                                .requestMatchers("**/auth/**").permitAll()
                                .anyRequest().authenticated()
                                .and()
                                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                                .and()
                                .addFilter(authenticationFilter())
                                .addFilter(new JwtAuthorizationFilter(authenticationManager, jwtUserDetailsService, secret))
                                .logout(logout -> logout
                                        .clearAuthentication(true)
                                        .logoutUrl("/logout")
                                        .invalidateHttpSession(true)
                                        .deleteCookies("JSESSIONID"))
                                .exceptionHandling()
                                .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                })
                .httpBasic(Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public JsonObjectAuthenticationFilter authenticationFilter() throws Exception {
        JsonObjectAuthenticationFilter filter = new JsonObjectAuthenticationFilter();
        filter.setAuthenticationSuccessHandler(authSuccessHandler);
        filter.setAuthenticationManager(authenticationManager);
        return filter;
    }

}

CodePudding user response:

You cant logout a JWT, a JWT is valid as long as you have set the validation time to be.

OWASP has written about this problem No Built-In Token Revocation by the User

You have written a custom login that issues tokens. The server has no idea how many tokens that have been issued and which tokens that are logged in or not.

So no you can't logout the user, unless you keep some form of state of the issued tokens on the server side, as in storing the tokens in a database and invalidating them when someone does a logout.

And ofc deleting the sessionid cookie wont do anything since you are not using session cookies.

This is the exact reason why you shouldn't be using JWTs as session replacements.

Stop using JWT for sessions

Stop using JWT for sessions, part 2

JSON Web Tokens (JWT) are Dangerous for User Sessions

Why JWTs Suck as Session Tokens

  • Related