繁体   English   中英

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

[英]Spring Security - Retaining URL parameters on redirect to login

好。

假设我有一个安全的网址模式

/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始终是/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) {
        super(loginFormUrl);
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
        redirectStrategy.sendRedirect(request, response, getLoginFormUrl() + "?" + request.getQueryString());
    }
}

Rizier123,再次感谢您的指点。

kabal -

我有非常相似的要求,我跟着你和zagyi狮子的帖子,但我似乎仍然松开/ 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时,它才会启动。 在上面的配置中,我不确定弹簧是否会在发生这种情况时内部抛出此类异常。

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

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

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)

谢谢,圣

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM