Search code examples
javaspringspring-securitythymeleaf

Is it possible to allow access to a page only through redirection?


I'm working on an application using Spring Boot and Thymeleaf.

I have the following snippet in my custom login page:

<p th:if="${param.logout}">Logged out successfully</p>

This paragraph is associated with the following security config:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/", "*.css").permitAll()
            .antMatchers("/myendpoint").authenticated()
            .and()
            .formLogin().loginPage("/login").permitAll()
            .and()
            .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout")
                .permitAll();
}

So after a logout the user is redirected to /login?logout and the logout message is shown.

My problem is this message is also shown when the user explicitly navigates to /login?logout by simply writing http://myserver:8080/login?logout into the browser.

Is it possible to prevent the user from directly accessing /login?logout (and thus show the message only when an actual logout happens)?


Solution

  • After some research i came up with using RedirectAttributes and addFlashAttribute() to pass data to my login page on a logout.

    So instead of setting logout as a query param, i removed Spring's default logout handling from my security config:

    http
        .authorizeRequests()
        .antMatchers("/", "*.css").permitAll()
        .antMatchers("/myendpoint").authenticated()
        .and()
        .formLogin().loginPage("/login").permitAll();
    

    And created the following custom logout endpoint in my controller:

    @PostMapping("/logout-user")
    public String logout(HttpServletRequest request, RedirectAttributes attrs) {
        new SecurityContextLogoutHandler().logout(request, null, null);
    
        // this attribute will be received in /login
        attrs.addFlashAttribute("logout", true);
    
        return "redirect:/login";
    }
    

    So i send my logout request to this endpoint and check for the logout attribute in /login, to show the logout message when appropriate:

    <p th:if="${logout}">Logged out successfully</p>
    

    It seems to be working flawlessly.