Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SessionAttributes when open new browser tabs

I have an Spring-mvc application and in each controller I add a form to SessionAttributes to preserve properties when save, delete or do another get request. Main problem becomes when I try to open some link in another browser tab and try to submit the first one. I tried this solution but when I do a redirect (in controller I only have 1 return for view and the other methods do a redirect) it creates a new conversation and can't find previous one.

I have another question about this triying to use spring-session, question It's here but I don't know if this will work too.

like image 765
Raider Avatar asked Mar 22 '16 15:03

Raider


2 Answers

Did you look into Spring's RedirectAttributes? I haven't used it myself but it sounds like it should do what you would like. RedirectAttributes is typically used for GET/redirect/POST patterns and at least one user seems to think passing session attributes this way is bad practice, however they go on to mention there doesn't seem to be a better solution. Anyway, the example shown in the documentation:

@RequestMapping(value = "/accounts", method = RequestMethod.POST)
public String handle(Account account, BindingResult result, RedirectAttributes redirectAttrs) {
    if (result.hasErrors()) {
        return "accounts/new";
    }
    // Save account ...
    redirectAttrs.addAttribute("id", account.getId()).addFlashAttribute("message", "Account created!");
    return "redirect:/accounts/{id}";
}

would add the "message" attribute to a RedirectModel, and if your controller redirects, then whatever method handles the redirect can access that data like so:

@RequestMapping(value = "/accounts", method = RequestMethod.POST)
public String handleRedirect(Model model) {
    String message = (String) model.asMap().get("message");
    return new ModelAndView();
}

So adding session attributes should be possible in the same way. Another reference here.

EDIT I was looking through the Spring documentation and they also mention this annotation @SessionAttributes. From the documentation:

The type-level @SessionAttributes annotation declares session attributes used by a specific handler. This will typically list the names of model attributes or types of model attributes which should be transparently stored in the session or some conversational storage, serving as form-backing beans between subsequent requests.

Could this be what you need?

And also a link to documentation on flash attributes.

like image 135
heisbrandon Avatar answered Oct 01 '22 21:10

heisbrandon


This is the solution we have come up with, nothing to do with Spring:

  1. On each html form of your application you will have to include a hidden field. Let's name this field CSRF_TOKEN. This field should have a randomly generated value. This value is placed both in the session and the hidden field. The name of the session attribute is SESSION_CSRF_TOKEN

  2. When the form is submitted to the server, you check whether the value in the session (SESSION_CSRF_TOKEN) equals the value sent in the HTTP request parameter CSRF_TOKEN. If not, you show some kind of error message and you stop processing. If they are equal, proceed.

If the user opens a new tab or duplicates a tab, the server will re-render the page and a new CSRF_TOKEN will be generated. So the user will only be able to submit the form from the newly opened tab , and not from the original.

This solution offers an additional bonus: It protects from CSRF attacks.

like image 34
chrisl08 Avatar answered Oct 01 '22 19:10

chrisl08