0

Its my first attempt to Spring Security, so the final solution for my question may be easy. So... I have an index page, which has only sign in form:

<form name="loginForm" action="login.html" method="post">
<table>
    <tr>
        <td><@spring.message "form.email" /></td>
        <td><input type="text" name="email" /></td>
    </tr>
    <tr>
        <td><@spring.message "form.password" /></td>
        <td><input type="password" name="password" /></td
    </tr>
</table>
    <input type="submit" value="${signIn}" />
</form>
<form name="" action="createAccount.html">
    <input type="submit" value="${register}" />
</form>

when im POST request, it is handled by controller. In My Controller I retrieve UserAccount data from DB and pass it to another page called "account.html".

This controller method is posted below:

@RequestMapping(value = "/login", method = RequestMethod.POST)
    public String logUserAccount(@RequestParam(value = "email", required = false) String email,
            @RequestParam(value = "password", required = false) String password, RedirectAttributes redirect) {
        try {

            UserAccount userAccount = userAccountService.signIn(email, password);
            redirect.addFlashAttribute("userAccount", userAccount);

            return "redirect:account.html";

        } catch (InvalidCreditnailsException e) {
            return RedirectController.REDIRECT_TO_INDEX_VIEW;
        }
    }

And Next controller method, which put user account data to model and render account.html page:

@RequestMapping(value = "/account", method = RequestMethod.GET)
    public String accountWindow(@ModelAttribute("userAccount") UserAccount userAccount, Model model){
        model.addAttribute("userAccount", userAccount);
        return "account";
    }

Now, I want to secure account.html page, preventing non authorized users to go directly to /account.html page. But my configuration of Spring Security is not correct. It looks like this:

<security:http>
        <security:intercept-url pattern="/account**" access="ROLE_USER" />
        <security:form-login
            login-page="/index.html"
            login-processing-url="/login.html"
            default-target-url="/account.html"
            username-parameter="email"
            password-parameter="password" 
         />
        <security:logout />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="test@gmail.com" password="qwerty" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>

What it does actually? When Im trying to access /account.html directly it redirect me to index.html where I have sign In form. Thats fine. But when Im log in Spring Security redirect me directly to /account.html page, Instead of sending /login.html request to my login controller for retrieve user data.

How to set up this> Any Ideas? Maybe my approach is not correct? I want only index and register page to be available for all guests. Rest of the page only for logged users.

Thank you for your help.

G.Spansky
  • 852
  • 6
  • 17
  • 32

1 Answers1

1

Sounds like you need to get your user account from the current context because you are already logged in. For example: You log in, close the browser, open a new browser window, and navigation to /account.html. You should still be able to reach /account.html because you have an active session on the server.

You may want to consider doing the following in your AccountController:

Retrieve the authenticated user:

Authentication auth = SecurityContextHolder().getContext().getAuthentication();

Get the user's username:

String username = auth.getName();

Get the user's account object:

UserAccount userAccount = userService.getAccount(username);

Alternatively, you can add a Principal argument to your AccountController to automatically inject the Principal.

@RequestMapping(value = "/account", method = RequestMethod.GET)
public String accountWindow(Model model, Principal principal){
    UserAccount userAccount = userService.getAccount(principal.getName());
    model.addAttribute("userAccount", userAccount);
    return "account";
}
John Miller
  • 74
  • 2
  • 6
  • The answer to this question may help as well: http://stackoverflow.com/questions/31159075/how-to-find-out-the-currently-logged-in-user-in-spring-boot – John Miller Jan 27 '16 at 15:01