Spring安全重定向到登录并恢复以前输入的表单数据
概述Spring安全重定向到登录并恢复以前输入的表单数据,spring,redirect,login,spring-security,restore,Spring,Redirect,Login,Spring Security,Restore,概述 我使用Spring安全性保护Spring Web应用程序 在站点上有一个表单可以输入一些数据,这个表单是公共的,但是数据将只为经过身份验证的用户处理 如果用户按下提交按钮但尚未登录,他将被委派到登录页面。如果登录成功,用户将被重定向到数据处理结果可见的站点 问题 在标准配置中,用户设置的所有数据在登录过程后丢失。据我所知,这是因为登录后为重定向创建了一个新的HttpRequest 解决方案 @Configuration @Order(SecurityProperties.ACCESS_OV
@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"));
}
}
@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);
}
}
自定义入口点
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);
}
}
您会怎么说,这是恢复表单数据的有效方法吗?更好的/其他的解决方案是否是spring中的标准方法
更新
似乎我的配置仍然有问题,因为在调试消息中可以看到,请求没有被“HttpSessionRequestCache”保存。如果我能做到这一点,我就不必使用自定义实现
o.s.s.w.util.matcher.AndRequestMatcher:尝试使用Ant[pattern='/**',GET]进行匹配
o、 s.s.w.u.matcher.AntPathRequestMatcher:请求“POST/user/dashboard”与“GET”不匹配/**
o、 s.s.w.util.matcher.AndRequestMatcher:不匹配
o、 s.s.w.s.HttpSessionRequestCache:未保存为配置的RequestMatcher的请求不匹配
请确保表单方法为post像这样
<form th:action="@{/login}" method="post">
<!-- form input -- >
</form>
请确保表单方法为post
像这样
<form th:action="@{/login}" method="post">
<!-- form input -- >
</form>
保存的请求感知包装的全部要点是,在登录后保存并还原上一个请求(或导致登录的请求)。如果这不起作用,那么您的设置也有问题。这也是我所期望的,但是org.springframework.security.web.savedrequest.HttpSessionRequestCache.saveRequest(HttpServletRequest,HttpServletResponse)中的匹配器似乎有些问题不起作用。匹配程序只包含“requestMatchers=[Ant[pattern='/**',而不是我所配置的…”调试消息还显示“正在尝试使用Ant[pattern='/**',GET]进行匹配”->“请求”POST/user/dashboard“不匹配”“GET/**”“不匹配”->“未保存为配置的请求匹配”看一看:您也可以实现自己的RequestMatcher来解决这个问题。可能与csrf筛选器有关?请确保表单方法是这样post的。保存的请求感知包装的全部要点是前一个请求(或导致登录的请求)登录后保存并还原。如果这不起作用,您的设置中会出现错误。这也是我所期望的,但似乎org.springframework.security.web.savedrequest.HttpSessionRequestCache.saveRequest(HttpServletRequest,HttpServletResponse)中的匹配程序出现问题。匹配程序只包含“requestMatchers=[Ant[pattern='/**'”而不是我所配置的…调试消息也会说“尝试使用Ant[pattern='/**',GET]进行匹配”->“请求”POST/user/dashboard“不匹配”“GET/**”“不匹配”->“保存为已配置RequestMatcher的请求不匹配”"看一看:你也可以实现你自己的RequestMatcher来解决这个问题。可能与csrf过滤器有关?请确保表单方法是这样发布的抱歉,但这个解决方案根本与问题无关,我认为你甚至没有解决这个问题…但无论如何,这是5年前的事,在我的设置中是一个问题,正如M.Deinum所说,保存的请求感知包装器负责完成我想要的事情对不起,但是这个解决方案与问题根本没有关系,我想你甚至没有解决这个问题……但无论如何,这是5年前的事了,在我的设置中是个问题,正如M.Deinum所说,保存的请求感知包装器负责完成所有的事情我想要的