justanoob
justanoob

Reputation: 1807

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)?

Upvotes: 5

Views: 585

Answers (3)

justanoob
justanoob

Reputation: 1807

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.

Upvotes: 1

jzheaux
jzheaux

Reputation: 7792

Another possibility might be to do a forward:

http
    .logout()
        .logoutSuccessHandler(
            (request, response, authentication) -> {
                request.setAttribute("loggedOut");
                request.getRequestDispatcher("/logged-out")
                       .forward(request, response);
            });

// ...

@Controller
class LoggedOutController {
    @PostMapping("/logged-out")
    public String loggedOut() {
        return "login";
    }
}

Where /logged-out renders the login page, just using a request attribute instead of a parameter to show the appropriate message.

Upvotes: 0

Viji
Viji

Reputation: 1

Try this.

Create Class like follow

AppConstant

public class AppConstant 
{
    public static final String USER = "user";
}

Util

public class Util {
    public static boolean checkSessionExist(HttpServletRequest request)

    {
        HttpSession session = request.getSession();
        if(session.getAttribute(AppConstant.USER) == null)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
}

Login Method

if(//Login credentials)
{
    session.setAttribute(AppConstant.USER, usermaster);
    //usermaster= it is object of your user master
}

Page Redirection

    UserMaster  usermaster = (UserMaster) session.getAttribute(AppConstant.USER);
    if(!Util.checkSessionExist(request))
    {
        return "redirect:login";
    }
    else
    {
         //Your Pager
    }

Use this method for every page redirection function.

Upvotes: 0

Related Questions