如何在验证后使Spring Security重定向到指定路径

时间:2016-01-27 14:21:20

标签: spring spring-mvc spring-security

这是我第一次尝试使用Spring Security,因此我的问题的最终解决方案可能很简单。所以... 我有一个索引页面,只有登录形式:

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

当im POST请求时,它由控制器处理。在我的控制器中,我从数据库中检索UserAccount数据并将其传递给另一个名为“account.html”的页面。

此控制器方法发布如下:

@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;
        }
    }

和Next控制器方法,将用户帐户数据放入模型并呈现account.html页面:

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

现在,我想保护account.html页面,防止非授权用户直接访问/account.html页面。但我的Spring Security配置不正确。它看起来像这样:

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

它实际上做了什么?当我试图直接访问/account.html时,它会将我重定向到我已登录表单的index.html。没关系。但是当我登录Spring Security时,我会直接将我重定向到/account.html页面,而不是将/login.html请求发送到我的登录控制器以检索用户数据。

如何设置此&gt;有任何想法吗?也许我的方法不正确?我想只为所有客人提供索引和注册页面。其余页面仅供登录用户使用。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您需要从当前上下文中获取用户帐户,因为您已经登录。例如:您登录,关闭浏览器,打开新的浏览器窗口,然后导航到/account.html。您仍然可以访问/account.html,因为您在服务器上有一个活动会话。

您可能需要考虑在AccountController中执行以下操作:

检索经过身份验证的用户:

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

获取用户的用户名:

String username = auth.getName();

获取用户的帐户对象:

UserAccount userAccount = userService.getAccount(username);

或者,您可以向AccountController添加Principal参数以自动注入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";
}