Spring Security OAuth 登錄與 WebFlux

Spring Security,Spring WebFlux
Remote
0
04:47 AM · Nov 30 ,2025

1. 概述

Spring Security 添加了 WebFlux 從 5.1.x GA 版本開始的 OAuth 支持。

我們將討論 如何配置我們的 WebFlux 應用程序以使用 OAuth2 登錄支持。 我們還將討論如何使用 WebClient 訪問受 OAuth2 保護的資源。

Webflux 的 OAuth 登錄配置與標準 Web MVC 應用程序的配置類似。 欲瞭解更多信息,請參閲我們的 Spring OAuth2Login 元素文章。

2. Maven 配置

首先,我們將創建一個簡單的 Spring Boot 應用,並將以下依賴添加到我們的 pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-client</artifactId>
</dependency>

spring-boot-starter-security, spring-boot-starter-webfluxspring-security-oauth2-client 依賴可在 Maven Central 上找到。

3. 主控制器接下來,我們將添加一個簡單的控制器,在主頁上顯示用户名:

@RestController
public class MainController {
    
    @GetMapping("/")
    public Mono<String> index(@AuthenticationPrincipal Mono<OAuth2User> oauth2User) {
       return oauth2User
        .map(OAuth2User::getName)
        .map(name -> String.format("Hi, %s", name));
    }
}

請注意,我們將從 OAuth2 客户端 UserInfo 端點獲取用户名

4. 使用 Google 登錄

現在,我們將配置我們的應用程序以支持使用 Google 登錄。

首先,我們需要在 Google 開發者控制枱 中創建一個新項目。

現在,我們需要添加 OAuth2 憑據(創建憑據 > OAuth 客户端 ID)。

接下來,我們將將其添加到“授權重定向 URI”中:

http://localhost:8080/login/oauth2/code/google

然後,我們需要配置我們的 application.yml 以使用客户端 ID 和密鑰

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: YOUR_APP_CLIENT_ID
            client-secret: YOUR_APP_CLIENT_SECRET

由於我們有 spring-security-oauth2-client 在路徑中,我們的應用程序將被安全保護。

用户將被重定向到使用 Google 登錄之前才能訪問主頁。

5. 使用身份提供者登錄我們還可以配置應用程序從自定義授權服務器進行登錄。

在以下示例中,我們將使用來自上一篇文章的授權服務器。

現在,我們需要配置更多屬性,不僅僅是 ClientID 和 Client Secret:

spring:
  security:
    oauth2:
      client:
        registration:
          custom:
            client-id: fooClientIdPassword
            client-secret: secret
            scopes: read,foo
            authorization-grant-type: authorization_code
            redirect-uri-template: http://localhost:8080/login/oauth2/code/custom
        provider:
          custom:
            authorization-uri: http://localhost:8081/spring-security-oauth-server/oauth/authorize
            token-uri: http://localhost:8081/spring-security-oauth-server/oauth/token
            user-info-uri: http://localhost:8088/spring-security-oauth-resource/users/extra
            user-name-attribute: user_name

在這種情況下,我們還需要指定 範圍授權類型重定向 URI對於 OAuth2 客户端。 此外,我們還將提供 授權令牌 URI對於授權服務器。

最後,我們需要配置 用户信息端點,以便可以獲取用户身份驗證詳細信息。

6. 安全配置

默認情況下,Spring Security 保護所有路徑。因此,如果只有單個 OAuth 客户端,我們將被重定向以授權該客户端並進行登錄。

如果註冊了多個 OAuth 客户端,則會自動創建一個登錄頁面以選擇登錄方法。

我們可以根據需要進行更改,並提供詳細的安全配置:

@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain configure(ServerHttpSecurity http) throws Exception {
        return http.authorizeExchange(auth -> auth
                .pathMatchers("/about").permitAll()
                .anyExchange().authenticated())
                .oauth2Login(Customizer.withDefaults())
                .build();
    }
}

在此示例中,我們已保護所有路徑,除了“/about”。

7. WebClient

我們還可以使用OAuth2除了僅驗證用户之外,還能使用WebClient來使用OAuth2AuthorizedClient訪問受OAuth2保護的資源。

現在,讓我們配置我們的WebClient:

@Bean
public WebClient webClient(ReactiveClientRegistrationRepository clientRegistrationRepo, 
  ServerOAuth2AuthorizedClientRepository authorizedClientRepo) {
    ServerOAuth2AuthorizedClientExchangeFilterFunction filter = 
      new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepo, authorizedClientRepo);
    
    return WebClient.builder().filter(filter).build();
}

然後,我們可以檢索一個受OAuth2保護的資源:

@Autowired
private WebClient webClient;

@GetMapping("/foos/{id}")
public Mono<Foo> getFooResource(@RegisteredOAuth2AuthorizedClient("custom") 
  OAuth2AuthorizedClient client, @PathVariable final long id){
    return webClient
      .get()
      .uri("http://localhost:8088/spring-security-oauth-resource/foos/{id}", id)
      .attributes(oauth2AuthorizedClient(client))
      .retrieve()
      .bodyToMono(Foo.class); 
}

注意,我們使用AccessTokenOAuth2AuthorizedClient檢索了遠程資源Foo

8. 結論

在本文中,我們學習瞭如何配置我們的 WebFlux 應用程序以使用 OAuth2 登錄支持,以及如何使用 WebClient 訪問受 OAuth2 保護的資源。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.