【发布时间】:2023-03-22 06:01:01
【问题描述】:
我正在尝试将 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 中添加 nonce 参数
我已经通过使用自定义 OAuth2AuthorizationRequest 来解决这个问题,该请求读取 custom-params 属性并将这些值附加到请求 URL
2。 OidcAuthorizationCodeAuthenticationProvider 抛出由 invalid_redirect_uri_parameter 引起的异常
我已经尝试了很多方法来解决这个问题。
我尝试创建一个过滤器,将 X-Forwarded-Proto 添加到请求中(因为代理不处理)。
添加了标题,我还添加了以下属性:
server:
forward-headers-strategy: native
tomcat.protocol-header: x-forwarded-proto
但它似乎不起作用。
OidcAuthorizationCodeAuthenticationProvider 仍然抛出异常,因为这个条件为假:
!authorizationResponse.getRedirectUri().equals(authorizationRequest.getRedirectUri())
我已经调试了代码,唯一的区别是一个是http,另一个是https。
我找到了一个我完全不喜欢的非常 hacky 的解决方案,它是另一个过滤器,它只针对该特定 URL 修改 URL。
我更喜欢更优雅的解决方案。
3.使用自定义nonce参数时,OidcAuthorizationCodeAuthenticationProvider会抛出由invalid_nonce引起的异常
现在我被困住了。我考虑过编写自己的身份验证提供程序,但我不能保证我的会在 Spring 提供的 OIDC 之前获得。
对于随机数,这是一个陷阱 22:
-
如果我不使用自定义参数,我找不到让 Spring 将 nonce 添加到请求中的方法
-
如果我使用那个,当它是 JWT 的一部分时 Spring 无法识别它并吓坏了
任何帮助都将不胜感激,因为这让我疯了几天甚至几周。
谢谢。
编辑
案例2比较的2个url来自:
- OAuth2AuthorizationRequest
- OAuth2AuthorizationResponse
OAuth2AuthorizationRequest 内置于 OAuth2AuthorizationRequestRedirectFilter 在以下行:
OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request);
重定向uri内置在调用的DefaultOAuth2AuthorizationRequestResolver.expandRedirectUri()中
UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request))
OAuth2AuthorizationResponse 内置在 OAuth2LoginAuthenticationFilter.attemptAuthentication() 中,它也调用
UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request))
然后
OAuth2AuthorizationResponseUtils.convert(params, redirectUri)
我会仔细检查,但我不记得在构建这些 URL 时调用了 UriComponentsBuilder.adaptFromForwardedHeaders(HttpHeaders headers)。
即使这样可行,仍然存在随机数问题:(
【问题讨论】:
-
当您说
x-forwarded-proto不起作用时,您是否确认您的代理正在发送该标头?如果您已验证代理正在发送该标头,您能否将x大写(我知道标头名称不区分大小写,但adaptFromForwardedHeaders使用X,所以只是以防万一) -
您可以在
org.springframework.web.util.UriComponentsBuilder.adaptFromForwardedHeaders(HttpHeaders headers)方法中放置一个断点,因为该方法似乎是提取重定向 uri 的方法 -
@KavithakaranKanapathippillai 标头设置为 X-Forwarded-Proto。检查我编辑的关于重定向 url 的帖子。
-
当您说 X-forwarded-proto 不起作用时,您是否验证过您的代理正在发送该标头?我找不到这个问题的答案。
because the proxy doesn't handle that.你的意思是代理没有添加那个标头吗? -
代理没有发送标头,这就是为什么我创建了一个过滤器来添加标头。显然它可以在另一个项目中使用,但是那个项目没有使用 Spring Boot 和最新的 Spring Security,而是手动处理 OIDC 身份验证。
标签: spring spring-boot spring-security openid-connect