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

问题描述 投票:9回答:3

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

我有标准表格登录由/postlogin上的弹簧过滤器处理。如果我去http://localhost/postlogin它会尝试登录我(失败因为我没有包含帖子参数),但做出了正确的尝试。

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

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

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

java authentication spring-mvc spring-security
3个回答
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,从而丢失新的会话对象和认证。

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

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


4
投票

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

要打开您需要的功能:

veb.hml

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

通过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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.