簡體   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