Spring安全“forward:”指令无法转发到登录表单

时间:2011-01-28 02:53:20

标签: java authentication spring-mvc spring-security

用户创建帐户后,我想自动登录该用户。

我在/postlogin上使用Springs过滤器处理标准表单登录。如果我转到http://localhost/postlogin,它会尝试登录我(失败,因为我没有包含帖子参数),但做出了正确的尝试。

但是如果我想以编程方式记录用户并且我尝试从控制器返回:“forward:/ postlogin”我得到404.

我假设forward:指令没有通过过滤器,因此UsernamePasswordAuthenticationFilter没有处理。

如何以编程方式手动诱导登录?我希望在用户创建新帐户后执行此操作(他们应在注册完成后立即登录该帐户)。

3 个答案:

答案 0 :(得分:17)

我误读了另一条指南,并意识到处理这个问题的正确方法如下:

1)在SecurityContextHolder上手动设置身份验证令牌

    UsernamePasswordWithAttributesAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( loadUserByUsername(username), password, authorities );
    SecurityContextHolder.getContext().setAuthentication(authenticationToken);

2)此时不呈现页面或使用forward:指令。您必须使用redirect:指令。

return "redirect:/accountcreated";

如果您渲染页面页面将正常加载,但会话对象将丢失,因为将创建一个新的j_session_id,但不会在浏览器中间请求它,并且下一个请求将使用旧的j_session_id,松散新会话对象& authetication。

使用forward:指令将绕过身份验证过滤器,没有用。

但重定向:使更新的会话信息进入浏览器。

答案 1 :(得分:4)

Servlet 2.4中的新过滤功能基本上缓解了过滤器只能在应用服务器处理实际请求之前和之后的请求流中运行的限制。相反,Servlet 2.4过滤器现在可以在每个调度点与请求调度程序进行交互。这意味着当Web资源将请求转发给另一个资源(例如,将请求转发到同一应用程序中的JSP页面的servlet)时,过滤器可以在目标资源处理请求之前运行。它还意味着如果Web资源包含来自其他Web资源的输出或函数(例如,包含多个其他JSP页面的输出的JSP页面),Servlet 2.4过滤器可以在每个包含的资源之前和之后工作。 。

要启用您需要的功能:

<强>的web.xml

<filter>   
    <filter-name>springSecurityFilterChain</filter-name>   
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter>  
<filter-mapping>   
    <filter-name>springSecurityFilterChain</filter-name>   
    <url-pattern>/<strike>*</strike></url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

<强>这个RegistrationController

return "forward:/login?j_username=" + registrationModel.getUserEmail()
    + "&j_password=" + registrationModel.getPassword();

答案 2 :(得分:2)

通过REST(Jersey)进行Spring身份验证

只是为了说明@David的答案(尽可能简化):

@POST
@Path("login")
public Response login(@FormParam("login") String login, @FormParam("pass") String pass)
{
    if (yourCheck(login, pass))
    {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        Authentication auth = new UsernamePasswordAuthenticationToken(login, pass, authorities);
        SecurityContextHolder.getContext().setAuthentication(auth);

        // IMPORTANT: Do not pass any data in the response body

        // show empty 200 page (suitable for REST clients)
        return Response.ok().build();
        // or redirect to your home page (for web UI)
        return Response.temporaryRedirect(new URI("/homepage/")).build();
    }
    else
    {
        return Response.status(Status.UNAUTHORIZED).build();
    }
}