gotch4
gotch4

Reputation: 13269

Why SpringSecurity, after a logout, keeps giving the same authenticated Principal

So I am using Spring Security with Spring Boot. I wanted to make my own AuthenticationProvider, that was using the db in my very own way, so I did it with this authenticate method:

@Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String email = authentication.getName();
        String password = authentication.getCredentials().toString();


        UserWithEmail userWithEmail = authService.getUserByEmail(email);
        if (userWithEmail == null)
            return null;
        if (userWithEmail.getPassword().equals(password)) {



            UsernamePasswordAuthenticationToken authenticated_user = new UsernamePasswordAuthenticationToken(userWithEmail, password, Arrays.asList(REGISTERED_USER_SIMPLE_GRANTED_AUTHORITY));
            return authenticated_user;
        } else {
            return null;
        }
    }

This, if I use the default /login page with the form, works well and after that if I add the following ModelAttribute to a Controller, it gets correctly filled with the UserWithEmail object:

@ModelAttribute("userwithemail")
    public UserWithEmail userWithEmail(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        Object principal = authentication.getPrincipal();
        if (principal instanceof UserWithEmail)
            return (UserWithEmail) principal;
        else
            return null;

    }

The problem is that if I hit /login?logout, it correctly displays that I am logged out, but if I go through the controller again I still get the same UserWithEmail object as principal and it has the property authenticated=true

This is my Java config for spring security:

http
                .formLogin()
                .defaultSuccessUrl( "/" )
                .usernameParameter( "username" )
                .passwordParameter( "password" )
                .and()

                .logout().invalidateHttpSession(true).deleteCookies("JSESSIONID").permitAll().and()

                .authorizeRequests()
                .antMatchers("*/**").permitAll()
                .antMatchers("/static/**").permitAll()
                .antMatchers("/profile").hasRole(MyAuthenticationProvider.REGISTERED_USER_AUTH)

                .and().authenticationProvider(getAuthProvider());

I'm new to Spring Security so maybe I'm missing something... can anyone help?

Upvotes: 0

Views: 527

Answers (1)

gotch4
gotch4

Reputation: 13269

According to the docs here for CSRF POST is mandatory for logging out, together with the CSRF token for attack protection.

Because I am using a custom templating engine I had to intercept the CSRF token in a model attribute from the request, like this:

@ModelAttribute("crsf_token")
public CsrfToken getcrsfToken(HttpServletRequest request, Model model) {
    CsrfToken token = (CsrfToken) request.getAttribute("_csrf");

    return token;
}

because it was not getting copied in the model for my templating engine.

Upvotes: 1

Related Questions