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 被配置为过滤所有端点。

另外,httpBasicformLogin 默认不会初始化,因此无需主动禁用它们。

【讨论】:

我无法导入 OrSecurityWebExchangeMatcher。它是 boot:spring-boot-starter-security 库的一部分吗? 抱歉这里的错字,已更正。

以上是关于Spring 安全性未重定向到给定的 OAuth 身份验证 URL的主要内容,如果未能解决你的问题,请参考以下文章

Grails Spring Security登录失败未重定向到登录视图

Spring Boot 应用程序未重定向到托管在不同服务器上的 Keycloak

Spring Oauth和安全性在登录成功后重定向到/ login

由于连接不安全,Okta 未重定向

okta oauth2 Spring security 所有受保护的页面重定向到登录

成功登录后登录页面未重定向到主页