简体   繁体   English

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

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

ok. 好。

lets say I have a secure url pattern 假设我有一个安全的网址模式

/secure/link-profile

optionally, there can be url paramaters appended. 可选地,可以附加url参数。

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

how can I make it so that those url params are carried over to the login page? 我怎样才能将这些url params转移到登录页面?

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

the basic premise is that we offer rewards integration with a 3rd party, who will send their users to us. 基本前提是我们提供与第三方的奖励整合,第三方会将用户发送给我们。 They will be taken to a page to link their 3rd party account/profile with their/our website user. 他们将被带到一个页面,将他们的第三方帐户/个人资料与他们/我们的网站用户链接。 If however, they dont have an existing account with us, then on the login page, they will go to the signup page, and we would then like to prepopulate some of their details that the 3rd party has passed on to us. 但是,如果他们没有我们的现有帐户,那么在登录页面上,他们将进入注册页面,然后我们希望预先填充第三方传递给我们的一些细节。

thanks in advance 提前致谢

spring security 2.0.7.RELEASE spring framework 3.1.1.RELEASE spring security 2.0.7.RELEASE spring framework 3.1.1.RELEASE

See the method buildRedirectUrlToLoginPage(HttpServletRequest request, ...) in LoginUrlAuthenticationEntryPoint . 请参阅LoginUrlAuthenticationEntryPoint的方法buildRedirectUrlToLoginPage(HttpServletRequest request, ...)

If I understood correctly what you want to achieve, I think it should be enough to override this method in a sublclass, copy the original method, but additionally call urlBuilder.setQuery(request.getQueryString()) when it builds the url. 如果我理解了你想要实现的目标,我认为应该足以在子类中覆盖这个方法,复制原始方法,但是在构建url时还要调用urlBuilder.setQuery(request.getQueryString())

Then you only need to configure the ExceptionTranslationFilter with this customized entry point. 然后,您只需要使用此自定义入口点配置ExceptionTranslationFilter

as per @zagyi's response I just overrode a method in my existing extension of AuthenticationProcessingFilterEntryPoint 根据@ zagyi的回复,我只是覆盖了我现有的AuthenticationProcessingFilterEntryPoint扩展中的方法

the method to override is protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) which is called by buildRedirectUrlToLoginPage(.. 覆盖的方法是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();
}

obviously that could be improved to also use a builder of sorts, catering for an existing query string on the url, but at this time I know my login url is always /login/ , so this is fine for my purposes 显然,可以改进以使用各种类型的构建器,为网址上的现有查询字符串提供服务,但此时我知道我的登录URL始终是/login/ ,所以这对我的目的来说很好

A different article explains how overriding does not work. 一篇文章解释了覆盖是如何起作用的。 I needed to override commence . 我需要覆盖开始 This may perhaps be a new thing that was introduced in later versions of spring security. 这可能是更新版本的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, thanks again for your pointers. Rizier123,再次感谢您的指点。

Hi kabal - kabal -

I have very similar requirements, and I followed yours and zagyi 's and lion's post, but I still seem to loose the original request parameter on /login page. 我有非常相似的要求,我跟着你和zagyi狮子的帖子,但我似乎仍然松开/ login页面上的原始请求参数。

Here's what I have: 这就是我所拥有的:

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()));
}

I can see that AuthenticationProcessingFilterEntryPoint is deployed, but it does not hit a breakpoint there. 我可以看到部署了AuthenticationProcessingFilterEntryPoint,但它没有在那里遇到断点。

Based on the documentation , it appears that this will kick in only when there is AuthenticationException or AccessDeniedException. 根据文档 ,只有在存在AuthenticationException或AccessDeniedException时,它才会启动。 In the configuration above, I am not sure if the spring internally throws such exception when such happens. 在上面的配置中,我不确定弹簧是否会在发生这种情况时内部抛出此类异常。

Additionally, I'd like to to preserve the query parameter on the landing page regardless authentication succeeds or not. 此外,无论身份验证成功与否,我都希望在登录页面上保留查询参数。

I did add success and failure handler, but none would kick into action. 我确实添加了成功和失败处理程序,但没有人会采取行动。

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);
}

I am using spring-security 3.2.4.RELEASE on spring boot 1.1.6.RELEASE(which in turn uses Spring framework 4.0.7.RELEASE) 我在spring boot 1.1.6.RELEASE上使用spring-security 3.2.4.RELEASE(后者又使用Spring framework 4.0.7.RELEASE)

Thanks, San 谢谢,圣

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

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