Spring 安全性未重定向到给定的 OAuth 身份验证 URL
Posted
技术标签:
【中文标题】Spring 安全性未重定向到给定的 OAuth 身份验证 URL【英文标题】:Spring security not redirecting to given OAuth authentication URL 【发布时间】:2021-08-14 10:36:52 【问题描述】:我正在尝试使用 Spring Security 集成 oauth2,并添加了一些用于保护路径的安全规则。当我尝试访问安全 URL 时,它会重定向到默认身份验证 URL,而不是从 application.yml 文件中获取一个。有人可以帮助我了解我缺少什么吗?
yml 文件中的 OAuth 配置
spring:
security:
oauth2:
client:
registration:
testProvider:
client-id: test
client-secret: xxx
clientName: cas
authorization-grant-type: authorization_code
redirect-uri: https://x.y.com/login/oauth2/code/idc
provider:
testProvider:
authorization-uri: https://x.y.com/oauth2.0/authorize
user-info-uri: https://x.y.com/oauth2.0/profile
token-uri: https://x.y.com/oauth2.0/accessToken
user-name-attribute: id
安全依赖:
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
安全过滤器中配置的规则:
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SpringSecurityConfig
@Bean
@Order(1)
public SecurityWebFilterChain openAccess(ServerHttpSecurity http)
http.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/open"))
.authorizeExchange(exchanges -> exchanges.anyExchange().permitAll())
.httpBasic()
.disable()
.formLogin()
.disable();
return http.build();
@Bean
@Order(3)
public SecurityWebFilterChain oauthAccess(ServerHttpSecurity http)
http
.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/secure"))
.authorizeExchange(exchanges -> exchanges.anyExchange().authenticated())
.oauth2Login();
return http.build();
当我在浏览器中输入 url http://localhost:8080/secure 时,它会重定向到 http://localhost:8080/oauth2/authorization/testProvider .它没有采用 yml 文件中配置的授权 URL https://x.y.com/oauth2.0/authorize
代码上传到github:https://github.com/rajeevprasanna/webflux-oauth-test
【问题讨论】:
当您添加EnableWebfluxSecurity
时,您将覆盖默认安全性,您必须手动配置所有内容。这可能就是它不读取 yml 的原因。该文档显示了如何手动配置 oauth 客户端。
当我删除 securityMatcher 时,规则无法正常工作。它将进入适当的授权流程。使用 securityMatcher,授权流程失败。不知道为什么行为是冲突的
这似乎是 securityMatcher 的问题。如果我删除 securityMatcher,路由特定规则不起作用
【参考方案1】:
Spring Security 启动授权代码流的方式是首先重定向到它自己的OAuth2AuthorizationRequestRedirectFilter
端点。
然后,此端点将在 ClientRegistration
中查找值并重定向到您配置的值。
但是,我认为您的 securityMatcher
存在问题,因为它说 Spring Security 应该只参与以 /secure
开头的请求。一旦 Spring Security 重定向到 /oauth2/authorization/testProvider
,过滤器链就不会用于该请求(因为它不是以 /secure
开头的)。
为了解决这个问题,我相信你应该改变这个:
.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/secure"))
到这里:
.securityMatcher(new OrServerWebExchangeMatcher(
new PathPatternParserServerWebExchangeMatcher("/secure"),
new PathPatternParserServerWebExchangeMatcher("/oauth2")
))
另外,Spring Security 旨在为您在一个 DSL 配置中协商授权规则。虽然有两个不同的过滤器链有合理的用例,但您可以考虑只使用一个:
@Bean
public SecurityWebFilterChain web(ServerHttpSecurity http)
http
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/open").permitAll()
.pathMatchers("/secure").authenticated()
)
.oauth2Login(Customizer.withDefaults());
return http.build();
那么,额外的安全匹配器是不必要的,因为这个 DSL 被配置为过滤所有端点。
另外,httpBasic
和 formLogin
默认不会初始化,因此无需主动禁用它们。
【讨论】:
我无法导入 OrSecurityWebExchangeMatcher。它是 boot:spring-boot-starter-security 库的一部分吗? 抱歉这里的错字,已更正。以上是关于Spring 安全性未重定向到给定的 OAuth 身份验证 URL的主要内容,如果未能解决你的问题,请参考以下文章
Grails Spring Security登录失败未重定向到登录视图
Spring Boot 应用程序未重定向到托管在不同服务器上的 Keycloak
Spring Oauth和安全性在登录成功后重定向到/ login