如何将 Spring 引导配置为在应用程序位于 SSL 终止代理后面时使用 OIDC



我正在尝试配置Spring Boot应用程序以使用OIDC。服务器位于 SSL 终止代理后面。

以下是我使用的属性:

spring:
security:
oauth2:
client:
provider:
oidc:
authorization-uri: https://example.org/oidc/oauth2/authorize
token-uri: https://example.org/oidc/oauth2/access_token
user-info-uri: https://example.org/oidc/oauth2/userinfo
jwk-set-uri: https://example.org/oidc/oauth2/connect/jwk_uri
custom-params: param_name1,param_value1,param_name2,param_value2,nonce,123456789
registration:
oidc:
client-id: myclientid
client-secret: myclientsecret
authorization-grant-type: authorization_code
scope:
- openid
- email
- profile
redirect-uri: https://mydomain/myapp/login/oauth2/code/oidc

这是它出错的地方:

1. OIDC 服务器要求在请求 URL 中添加随机数参数

我已经通过使用自定义 OAuth2AuthorizationRequest 解决了这个问题,该请求读取自定义参数属性并将这些值附加到请求 URL

2. OidcAuthorizationCodeAuthenticationProvider 抛出由 invalid_redirect_uri_parameter 导致的异常

我已经尝试了许多方法来解决此问题。

我尝试创建一个过滤器,将 X-Forwarded-Proto 添加到请求中(因为代理不处理它(。

添加了标头,我还添加了以下属性:

server:
forward-headers-strategy: native
tomcat.protocol-header: x-forwarded-proto

但它似乎不起作用。

OidcAuthorizationCodeAuthenticationProvider 仍然会引发异常,因为此条件为 false:

!authorizationResponse.getRedirectUri().equals(authorizationRequest.getRedirectUri())

我已经调试了代码,唯一的区别是一个是http,另一个是https。

我发现了一个我根本不喜欢的非常黑客的解决方案,这是另一个过滤器,它只针对该特定 URL 修改 URL。

我更喜欢一个更优雅的解决方案。

3. 使用自定义 nonce 参数时,OidcAuthorizationCodeAuthenticationProvider 会抛出异常原因,invalid_nonce

现在我被困住了。我考虑过编写自己的身份验证提供程序,但我不能保证我的身份验证提供程序会在 Spring 提供的 OIDC 提供程序之前被选中。

有了随机数,这是一个第 22 条:

  • 如果我不使用自定义参数,我找不到让 Spring 将随机数添加到请求的方法

  • 如果我使用那个,Spring 在它是 JWT 的一部分时无法识别它并吓坏

任何帮助将不胜感激,因为这已经让我发疯了几天甚至几周。

谢谢。

编辑

在案例 2 中比较的 2 个 URL 来自:

  • OAuth2授权请求
  • OAuth2授权响应

OAuth2AuthorizationRequest内置于 OAuth2AuthorizationRequestRedirectFilter 在以下行:

OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request);

重定向 uri 构建在 DefaultOAuth2AuthorizationRequestResolver.expandRedirectUri(( 中,它调用

UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request))

OAuth2AuthorizationResponse内置在 OAuth2LoginAuthenticationFilter.tryAuthentication(( 中,它也调用

UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request))

然后

OAuth2AuthorizationResponseUtils.convert(params, redirectUri)

我会仔细检查,但我不记得在构建这些 URL 时调用了 UriComponentsBuilder.adaptFromForwardedHeaders(HttpHeaders headers(。

即使这有效,这仍然会使随机数问题:(

我们偶然发现了同样的问题,问题主要是因为我们的服务器在反向代理后面,似乎代理以某种方式更改了 url 导致此检查失败

!authorizationResponse.getRedirectUri().equals(authorizationRequest.getRedirectUri())

此行在更高版本的 Spring 安全性中删除,在提交

24500fa3ca23aa23ede86dfcfe02113671d5b8bc

在 GitHub 提交

于 2019 年 12 月 6 日引入,在春季安全版本 5.1.13 中

因此,解决方案是将Spring boot升级到至少2.1.17,以获取Spring Boot 2.1.X系列版本。

虽然OP说他无法升级他的图书馆,但我希望这可以帮助那些可以升级的人。

我们还做了上面提到的解决方案,由Kavithakaran Kanapathippilla,并配置了我们的反向代理来添加X-forwarded-proto http标头,我也相信我们配置了spring启动应用程序属性来检查它们

用于在代理后面工作的 Spring 启动文档

最新更新