【问题标题】:Spring Security OAuth2 Redirect LoopSpring Security OAuth2 重定向循环
【发布时间】:2015-01-12 08:06:12
【问题描述】:

我有一个带有依赖项的 oauth2 客户端 spring-boot 应用程序: - 弹簧启动 1.2.0.RC1 - spring-security-oauth2 2.0.4.RELEASE - spring-security 3.2.5.RELEASE

客户端进行身份验证,身份验证在 SecurityContextHolder 中设置,但是当请求被重定向到原始 url 时,过滤器链再次开始处理。我注意到SecurityContextPersistenceFilter 中的 contextBeforeChainExecution 和 contextAfterChainExecution 都具有空身份验证。

我的部分代码基于 [1]Spring Security OAuth2 (google) web app in redirect loop

关于为什么重定向循环的任何想法?先感谢您。

[日志 sn-p]https://gist.github.com/yterradas/61da3f6eccc683b3a086

以下是安全配置。

@配置
公共类 SecurityConfig {

  @配置
  @EnableWebMvcSecurity
  受保护的静态类 WebSecurityConfig 扩展 WebSecurityConfigurerAdapter {

    @自动连线
    私人 OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationProcessingFilter;

    @自动连线
    私人 LoginUrlAuthenticationEntryPoint vaultAuthenticationEntryPoint;

    @SuppressWarnings({"SpringJavaAutowiringInspection"})
    @自动连线
    私人 OAuth2ClientContextFilter oAuth2ClientContextFilter;

    @覆盖
    受保护的无效配置(HttpSecurity http)抛出异常{
      // @格式化程序:关闭
      http
          .authorizeRequests()
            .antMatchers("/**").authenticated()
        。和()
          .exceptionHandling().authenticationEntryPoint(vaultAuthenticationEntryPoint)
        。和()
          .addFilterAfter(oAuth2ClientContextFilter, ExceptionTranslationFilter.class)
          .addFilterBefore(oAuth2ClientAuthenticationProcessingFilter, FilterSecurityInterceptor.class)
          .anonymous().disable();
    // @格式化程序:打开
    }

    @覆盖
    公共无效配置(WebSecurity web)抛出异常{
      // @格式化程序:关闭
    网络
       /* 去做:
       在生产中禁用调试
       */
       .调试(真);
    // @格式化程序:开启
    }
  }

  @配置
  @EnableOAuth2Client
  受保护的静态类 ClientSecurityConfig {

    @Value("${app.name}") 私有字符串 appId;
    @Value("${app.clientId}") 私有字符串 appClientId;
    @Value("${app.clientSecret}") 私有字符串 appClientSecret;
    @Value("${app.redirectUrl}") 私有字符串 appRedirectUrl;
    @Value("${vault.accessTokenUrl}") 私有字符串 vaultAccessTokenUrl;
    @Value("${vault.userAuthorizationUrl}") 私有字符串 vaultUserAuthorizationUrl;
    @Value("${vault.checkTokenUrl}") 私有字符串 vaultCheckTokenUrl;

    @SuppressWarnings({"SpringJavaAutowiringInspection"})
    @资源
    @Qualifier("oauth2ClientContext")
    私人 OAuth2ClientContext oAuth2ClientContext;

    @自动连线
    @Qualifier("安全数据源")
    私有数据源安全数据源;

    @自动连线
    私有 MappingJackson2HttpMessageConverter jackson2HttpMessageConverter;

    @豆角,扁豆
    公共 OAuth2RestOperations oAuth2RestOperations() {
      AccessTokenProviderChain 提供者 = 新的 AccessTokenProviderChain(
          Arrays.asList(新 AuthorizationCodeAccessTokenProvider())
      );
      provider.setClientTokenServices(new JdbcClientTokenServices(securityDataSource));

      OAuth2RestTemplate 模板 = 新 OAuth2RestTemplate(oAuth2Resource(), oAuth2ClientContext);
      模板.setAccessTokenProvider(提供者);
      template.setMessageConverters(Arrays.asList(jackson2HttpMessageConverter));

      返回模板;
    }

    @豆角,扁豆
    OAuth2ProtectedResourceDetails oAuth2Resource() {
      AuthorizationCodeResourceDetails 资源 = new AuthorizationCodeResourceDetails();

      资源.setId(appId);
      resource.setAuthenticationScheme(AuthenticationScheme.query);
      resource.setAccessTokenUri(vaultAccessTokenUrl);
      resource.setUserAuthorizationUri(vaultUserAuthorizationUrl);
      resource.setUseCurrentUri(false);
      resource.setPreEstablishedRedirectUri(appRedirectUrl);
      资源.setClientId(appClientId);
      资源.setClientSecret(appClientSecret);
      resource.setClientAuthenticationScheme(AuthenticationScheme.form);

      返回资源;
    }

    @豆角,扁豆
    ResourceServerTokenServices oAuth2RemoteTokenServices() {
      VaultTokenServices tokenServices = new VaultTokenServices();

      RestTemplate restOperations = new RestTemplate();
      restOperations.setMessageConverters(Arrays.asList(jackson2HttpMessageConverter));

      tokenServices.setRestTemplate(restOperations);
      tokenServices.setClientId(appClientId);
      tokenServices.setClientSecret(appClientSecret);
      tokenServices.setCheckTokenEndpointUrl(vaultCheckTokenUrl);

      返回令牌服务;
    }

    @豆角,扁豆
    LoginUrlAuthenticationEntryPoint oAuth2AuthenticationEntryPoint() {
      return new LoginUrlAuthenticationEntryPoint("/vaultLogin");
    }

    @豆角,扁豆
    OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationProcessingFilter() {
      OAuth2ClientAuthenticationProcessingFilter 过滤器 =
          新的 OAuth2ClientAuthenticationProcessingFilter("/vaultLogin");

      filter.setRestTemplate(oAuth2RestOperations());
      filter.setTokenServices(oAuth2RemoteTokenServices());

      返回过滤器;
    }

  }
}

【问题讨论】:

  • 授权服务器在哪里。它的检查令牌端点是否可用(你可以卷曲它)吗?
  • 授权服务器是一个单独的组件,不在同一个项目中。是的,我可以卷曲它。我可以看到正在创建授权,以及已启动对已保存请求的重定向。我不确定,但我认为上下文没有被保存。之所以这么想是因为执行前后的Context都有null认证。
  • 我特别询问您是否可以卷曲 /check_token 端点。它不是规范的一部分,因此取决于实现,它可能存在也可能不存在(您的客户似乎正在尝试使用它)。
  • @DaveSyer 是的,我可以卷曲它。另外,我有一个自定义的 RemoteTokenServices 来处理验证,因为授权服务器不使用 http-basic 进行验证。我已经用日志 sn-p 更新了这个问题。也许这会有所帮助。

标签: spring-security spring-boot spring-security-oauth2


【解决方案1】:

我找到了一个平庸的解决方案,它需要从SecurityFilterChain 中删除几乎所有过滤器。不幸的是,我没有我工作过的应用程序的工作副本。但是,通过在破坏应用程序之前删除尽可能多的过滤器,然后只添加必要的过滤器,应该很容易复制解决方案。如果我没记错的话,罪魁祸首是SecurityContextPersistenceFilterRequestCacheAwareFilter

【讨论】:

    【解决方案2】:

    对于其他可能遇到相同问题的人 - 使用 Spring Security oAuth 时出现重定向循环。我有这个是因为我位于阻止任何直接访问 Internet 的防火墙后面,并且我的 Spring Boot+Security 应用程序需要调用位于 Internet 上的 IdP 的 userinfo 端点,例如Okta、Google 等。您可以通过在本地运行配置中配置代理来修复它,如下所示:

    -Dhttp.proxyHost=yourhttpproxy.company.com 
    -Dhttp.proxyPort=yourhttproxyport
    -Dhttp.nonProxyHosts=”localhost|*.yourintranetdomain1.com|*.yourintranetdomain2.com|etc” 
    -Dhttps.proxyHost=yourhttpsproxy.company.com
    -Dhttps.proxyPort=yourhttpsproxyport 
    -Dhttps.nonProxyHosts=”localhost|*.yourintranetdomain1.com|*.yourintranetdomain2.com|etc”
    

    我希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      我认为您有 2 个OAuth2ClientContextFilters(一个由@EnableOAuth2Client 添加,您已手动将另一个添加到 Spring Security 过滤器链中)。您应该可以删除您添加的那个。

      【讨论】:

      • 我已经从 Spring Security 过滤器链中删除了OAuth2ClientContextFilter,但我仍然有重定向循环。让我知道我可以提供哪些其他信息。
      猜你喜欢
      • 2014-11-21
      • 2015-03-10
      • 1970-01-01
      • 2015-09-12
      • 1970-01-01
      • 2020-01-23
      • 2019-05-24
      • 2015-05-18
      • 2020-01-05
      相关资源
      最近更新 更多