Spring Security – 在重定向到登录时保留URL参数

好。

假设我有一个安全的url模式

/secure/link-profile 

可选地,可以附加url参数。

 /secure/link-profile?firstName=Bob&secondName=Smith&membershipNumber=1234 

我怎样才能将这些url params转移到登录页面?

 /login?firstName=Bob&secondName=Smith&membershipNumber=1234 

基本前提是我们提供与第三方的奖励整合,第三方会将用户发送给我们。 他们将被带到一个页面,将他们的第三方帐户/个人资料与他们/我们的网站用户联系起来。 但是,如果他们没有我们的现有帐户,那么在登录页面上,他们将进入注册页面,然后我们希望预先填充第三方传递给我们的一些细节。

提前致谢

spring security 2.0.7.RELEASE spring framework 3.1.1.RELEASE

请参阅LoginUrlAuthenticationEntryPoint的方法buildRedirectUrlToLoginPage(HttpServletRequest request, ...)

如果我正确理解了你想要实现的目标,我认为应该足以在子类中重写此方法,复制原始方法,但在构建url时还要调用urlBuilder.setQuery(request.getQueryString())

然后,您只需要使用此自定义入口点配置ExceptionTranslationFilter

根据@ zagyi的回复,我只是在我现有的AuthenticationProcessingFilterEntryPoint扩展中覆盖了一个方法

覆盖的方法是protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) ,由buildRedirectUrlToLoginPage(..

 @Override protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) { String url = super.determineUrlToUseForThisRequest(request, response, exception); return url + "?" + request.getQueryString(); } 

显然可以改进,也可以使用各种类型的构建器,为url上的现有查询字符串提供服务,但此时我知道我的登录url始终是/login/ ,所以这对我的目的来说很好

另一篇文章解释了覆盖是如何起作用的。 我需要覆盖开始 。 这可能是更新版本的spring security中引入的新东西。

 public class SecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final HttpSecurity httpSecurity) throws Exception { httpSecurity. formLogin().loginPage("/signIn").permitAll(). and(). authorizeRequests(). antMatchers(managementContextPath + "/**").permitAll(). anyRequest().authenticated().withObjectPostProcessor(objectPostProcessor). and(). csrf().disable(). contentTypeOptions(). xssProtection(). cacheControl(). httpStrictTransportSecurity(). and(). requestCache().requestCache(new RedisRequestCache(savedRequestRedisTemplate())). and(). sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy). and(). exceptionHandling().authenticationEntryPoint(new AuthenticationProcessingFilterEntryPoint("/signIn")); } } 
 public class AuthenticationProcessingFilterEntryPoint extends LoginUrlAuthenticationEntryPoint {
     public AuthenticationProcessingFilterEntryPoint(String loginFormUrl){
        超级(loginFormUrl);
     }

     @覆盖
     public void starts(HttpServletRequest请求,HttpServletResponse响应,AuthenticationException authException)抛出IOException,ServletException {
         RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
         redirectStrategy.sendRedirect(request,response,getLoginFormUrl()+“?”+ request.getQueryString());
     }
 }

Rizier123,再次感谢您的指点。

嗨kabal –

我有非常相似的要求,我跟着你和zagyi和狮子的post,但我似乎仍然松开/ login页面上的原始请求参数。

这就是我所拥有的:

 public class AuthenticationProcessingFilterEntryPoint extends LoginUrlAuthenticationEntryPoint { @Override protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) { String url = super.determineUrlToUseForThisRequest(request, response, exception); return url + "?" + request.getQueryString(); } } protected void configure(final HttpSecurity httpSecurity) throws Exception { httpSecurity. formLogin().loginPage("/signIn").permitAll(). and(). authorizeRequests(). antMatchers(managementContextPath + "/**").permitAll(). anyRequest().authenticated().withObjectPostProcessor(objectPostProcessor). and(). csrf().disable(). contentTypeOptions(). xssProtection(). cacheControl(). httpStrictTransportSecurity(). and(). requestCache().requestCache(new RedisRequestCache(savedRequestRedisTemplate())). and(). sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy). and(). addFilter(new ExceptionTranslationFilter(new AuthenticationProcessingFilterEntryPoint())); } 

我可以看到部署了AuthenticationProcessingFilterEntryPoint,但它没有在那里遇到断点。

根据文档 ,似乎只有在有AuthenticationException或AccessDeniedException时才会启动。 在上面的配置中,我不确定弹簧是否会在发生这种情况时内部抛出此类exception。

此外,无论身份validation成功与否,我都希望在登录页面上保留查询参数。

我确实添加了成功和失败处理程序,但没有人会采取行动。

 protected void configure(final HttpSecurity httpSecurity) throws Exception { httpSecurity. formLogin(). successHandler(new PropogateQueryStringAuthenticationSuccessHandlerImpl()). failureHandler(new SimpleUrlAuthenticationFailureHandlerImpl(new QueryStringPropagateRedirectStrategy())). and(). authorizeRequests(). antMatchers(managementContextPath + "/**").permitAll(). anyRequest().authenticated().withObjectPostProcessor(objectPostProcessor). and(). csrf().disable(). contentTypeOptions(). xssProtection(). cacheControl(). httpStrictTransportSecurity(). and(). requestCache().requestCache(new RedisRequestCache(savedRequestRedisTemplate())). and(). sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy); } 

我在spring boot 1.1.6.RELEASE上使用spring-security 3.2.4.RELEASE(反过来使用Spring framework 4.0.7.RELEASE)

谢谢,圣