【问题标题】:Spring Security Not Working After Upgrading to 3.2.0.RC2升级到 3.2.0.RC2 后 Spring Security 不工作
【发布时间】:2013-11-16 14:10:18
【问题描述】:

我刚刚从 Spring Security 3.2.0.RC1 升级到 3.2.0.RC2。在 RC1 下一切正常。在 RC2 下,我的自定义登录页面不再起作用。单击登录按钮后,登录页面将重新显示。如果提交了无效的凭据(或没有凭据),它还会重新显示而没有任何错误消息。如果凭据不正确,它将正确显示错误消息。

有趣的是,如果我改变:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    // @formatter:off

    httpSecurity
        .authorizeRequests()
            .antMatchers("/restricted/**").hasRole("admin"))
            // all requests must be authenticated
            .anyRequest().authenticated()
    .and()
        .formLogin()
            .loginPage("/myLoginUrl.request")
            .failureUrl("/myLoginUrl.request?error")
            .permitAll()
    .and()
        .logout()
            .permitAll()
            .logoutSuccessUrl("/myLoginUrl.request")
    ;
    // @formatter:on
}

到:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    // @formatter:off

    httpSecurity
        .authorizeRequests()
            .antMatchers("/restricted/**").hasRole("admin"))
            // all requests must be authenticated
            .anyRequest().authenticated()
    .and()
        .formLogin()
            .permitAll()
    .and()
        .logout()
            .permitAll()
            .logoutSuccessUrl("/myLoginUrl.request")
    ;
    // @formatter:on
}

会显示默认的 Spring Security 登录页面并且可以正常工作。我查看了默认页面的来源并将其与我的自定义页面进行了比较,它似乎对具有相同名称的字段调用了相同的操作。

如果我单步调试调试器,我发现在 AntPathMatcher.java 中,公共布尔匹配(HttpServletRequest 请求):

String url = getRequestPath(request)

使用我的自定义登录页面时返回的 url 是“/error”。 getRequestPath() 只返回附加到 request.getPathInfo() 的 request.getServletPath()。我不确定为什么升级到 RC2 会导致它返回“/error”。

【问题讨论】:

    标签: spring-mvc spring-security


    【解决方案1】:

    我改变了三件事,使这项工作奏效。

    1) 在表单中添加了一个 CSRF 隐藏字段:

    <input type="hidden" name="${_csrf.parameterName}"
        value="${_csrf.token}" /> 
    

    2)表单方法的大写POST:

    <form action="login" method="POST">
    

    3) 将 loginProcessingUrl 显式添加到配置中:

    .formLogin()
            .loginPage("/myLoginUrl.request")
            .loginProcessingUrl("/login")
            .failureUrl("/myLoginUrl.request?error")
            .permitAll()
    

    【讨论】:

    • 应该不需要使用 POST 而不是 post。如果您使用 post 以及您使用的是什么浏览器,会发生什么? loginPage("/login") 声明 GET /login 是登录表单。此外,除非明确设置,否则它将注销成功的默认值更新为 /login?logout login error 到 /login?error 和 POST /login 是登录处理 URL。
    • 你是对的。我已经切换回小写的“帖子”,它仍然有效。我认为“/错误”可能是由于缺少 CSRF 令牌引起的。这是 RC1 和 RC2 之间的变化吗?我以前不需要它。使用最新的 Chrome、IE 8 和最新的 Firefox 进行测试。一切正常。感谢您在这方面所做的工作,@Robb Winch。我见过的最好的安全解决方案。 Javaconfig 非常好。
    • 您应该需要 CSRF 令牌才能使用 RC1 登录,除非您使用 http.csrf().disabled() 禁用了它。如果您使用 Spring MVC 的标签库或 Thymeleaf 2.1+,则 CSRF 令牌会自动包含在表单中。
    猜你喜欢
    • 2013-11-16
    • 2023-02-04
    • 2014-04-10
    • 1970-01-01
    • 2013-09-25
    • 2014-02-07
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多