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

Dav*_*rks 9 java authentication spring-mvc spring-security

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

我有标准表单登录由弹簧过滤器处理/postlogin.如果我去http://localhost/postlogin它试图登录我(失败,因为我没有包括post参数),但做出了正确的尝试.

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

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

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

Dav*_*rks 17

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

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

    UsernamePasswordWithAttributesAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( loadUserByUsername(username), password, authorities );
    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
Run Code Online (Sandbox Code Playgroud)

2)此时不要渲染页面或使用forward:指令.您必须使用redirect:指令.

return "redirect:/accountcreated";
Run Code Online (Sandbox Code Playgroud)

如果您渲染页面页面将正常加载,但会话对象将丢失,因为将创建一个新的j_session_id,但不会在请求中的中间进入浏览器,下一个请求将使用旧的j_session_id,从而丢失新的会话对象和认证.

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

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


小智 5

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

要打开该功能,您需要:

网络.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>
Run Code Online (Sandbox Code Playgroud)

注册控制器

return "forward:/login?j_username=" + registrationModel.getUserEmail()
    + "&j_password=" + registrationModel.getPassword();
Run Code Online (Sandbox Code Playgroud)