23

好的。

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

/secure/link-profile

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

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

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

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

基本前提是我们提供与第三方的奖励集成,第三方会将他们的用户发送给我们。他们将被带到一个页面,以将他们的第 3 方帐户/个人资料与他们/我们的网站用户链接起来。但是,如果他们没有我们现有的帐户,那么在登录页面上,他们将转到注册页面,然后我们想预先填充他们的一些详细信息,这些详细信息是第 3 方传递给我们的。

提前致谢

春天安全 2.0.7.RELEASE 春天框架 3.1.1.RELEASE

4

4 回答 4

9

见中的方法buildRedirectUrlToLoginPage(HttpServletRequest request, ...)LoginUrlAuthenticationEntryPoint

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

然后你只需要配置ExceptionTranslationFilter这个自定义的入口点。

于 2013-01-11T18:49:37.503 回答
5

根据@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/,所以这对我的目的来说很好

于 2013-01-11T19:50:25.250 回答
5

一篇文章解释了覆盖如何不起作用。我需要覆盖开始。这可能是在更高版本的 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"));
    }
}
公共类 AuthenticationProcessingFilterEntryPoint 扩展 LoginUrlAuthenticationEntryPoint {
    公共 AuthenticationProcessingFilterEntryPoint(String loginFormUrl) {
        超级(登录表单网址);
    }

    @覆盖
    公共无效开始(HttpServletRequest 请求,HttpServletResponse 响应,AuthenticationException authException)抛出 IOException,ServletException {
        RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
        redirectStrategy.sendRedirect(request, response, getLoginFormUrl() + "?" + request.getQueryString());
    }
}

Rizier123,再次感谢您的指点。

于 2014-12-19T04:20:36.353 回答
0

卡巴尔-

我有非常相似的要求,我关注了你和zagyilion 的帖子,但我似乎仍然失去了 /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)

谢谢,桑

于 2014-12-17T05:52:04.690 回答