Spring安全性重定向到登录并恢复先前输入的表单数据

时间:2015-08-14 12:08:43

标签: spring redirect login spring-security restore

概述

  1. 我使用Spring Security保护Spring Web应用程序
  2. 在网站上有一个输入一些数据的表单,此表单是公开的,但只会为经过身份验证的用户处理数据
  3. 如果用户按下提交按钮但尚未登录,则他将被委派到登录页面。如果登录成功,用户将被重定向到可以看到数据处理结果的站点
  4. 问题

    在标准配置中,用户设置的所有数据在登录过程后都将丢失。据我所知,这是因为在登录后为重定向创建了一个新的HttpRequest。

    解决方案

    1. 我必须编写一个自定义的LoginUrlAuthenticationEntryPoint,它将表单数据存储在会话中
    2. 我必须编写一个自定义的SavedRequestAwareAuthenticationSuccessHandler,它从会话中读取日期并将它们作为参数添加到网址
    3. WebApp配置

      @Configuration
      @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
      public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
      
          @Autowired
          private SecurityProperties security;
      
          @Override
          public void configure(AuthenticationManagerBuilder auth) throws Exception {
      
              auth.inMemoryAuthentication()
                  .withUser("admin")
                  .password("admin")
                  .roles("ADMIN", "USER")
                  .and()
                  .withUser("user")
                  .password("user")
                  .roles("USER");
          }
      
          @Override
          protected void configure(HttpSecurity http) throws Exception {
      
                  http.authorizeRequests()
                      .antMatchers("/", "/inputForm")
                      .permitAll()
                      .anyRequest()
                      .authenticated()
                      .and()
                      .formLogin()
                      .loginPage("/login")
                      .permitAll()
                      .successHandler(new SavedRequestAwareAuthenticationSuccessHandlerCustom())
                      .and()
                      .csrf()
                      .and()
                      .logout()
                      .logoutUrl("/logout")
                      .logoutSuccessUrl("/")
                      .invalidateHttpSession(true)
                      .and()
                      .exceptionHandling()
                      .authenticationEntryPoint(new LoginUrlAuthenticationEntryPointCustom("/login"));
          }
      }
      

      自定义SuccessHandler

      public class SavedRequestAwareAuthenticationSuccessHandlerCustom extends SavedRequestAwareAuthenticationSuccessHandler {
      
          @Override
          public void onAuthenticationSuccess(
                  HttpServletRequest request,
                  HttpServletResponse response,
                  Authentication authentication) throws IOException, ServletException {
      
              String text = (String) request.getSession().getAttribute("text");
              if (text != null) {
                  request.getSession().removeAttribute("text");
                  setDefaultTargetUrl("/user/dashboard/?text=" + text);
              }
      
              super.onAuthenticationSuccess(request, response, authentication);
          }
      }
      

      自定义EntryPoint

      public class LoginUrlAuthenticationEntryPointCustom extends LoginUrlAuthenticationEntryPoint {
      
          public LoginUrlAuthenticationEntryPointCustom(String loginFormUrl) {
              super(loginFormUrl);
          }
      
          @Override
          public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
                          throws IOException,
                          ServletException {
      
              String text = request.getParameter("text");
              request.getSession().setAttribute("text", text);
      
              super.commence(request, response, authException);
          }
      }
      

      你会说,这是一种恢复表格数据的有效方法,是更好的/其他解决方案,也许是春天的标准方式?

      更新

      似乎我的配置仍有问题,因为在调试消息中看到,请求不会被" HttpSessionRequestCache"保存。如果我开始工作,我就不必使用自定义实现。

      o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using Ant [pattern='/**', GET] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /user/dashboard' doesn't match 'GET /** o.s.s.w.util.matcher.AndRequestMatcher : Did not match o.s.s.w.s.HttpSessionRequestCache : Request not saved as configured RequestMatcher did not match

1 个答案:

答案 0 :(得分:0)

请确保表单方法为post
像这样

<form th:action="@{/login}" method="post"> 
         <!-- form input -- >
</form>