1. 概述
Spring Security 從 5.1.x GA 版本開始,為 WebFlux 添加了 OAuth 支持。
我們將討論如何配置我們的 WebFlux 應用程序以使用 OAuth2 登錄支持。我們還將討論如何使用 WebClient 訪問受 OAuth2 保護的資源。
Webflux 的 OAuth2 登錄配置與標準 Web MVC 應用程序的配置類似。有關此內容的更多詳細信息,請參閲我們的 Spring OAuth2Login 元素文章。
2. Maven 配置
首先,我們將創建一個簡單的 Spring Boot 應用,並將以下依賴添加到我們的 <em pom.xml</em>> 中:
<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-webflux 和 spring-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 開發者控制枱 創建一個新的項目。
接下來,我們需要在“授權回調 URI”中添加 OAuth2 憑據(創建憑據 > OAuth 客户端 ID)。
http://localhost:8080/login/oauth2/code/google然後,我們需要配置我們的 application.yml,以便使用 Client ID 和 Secret:
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在這種情況下,還需要指定 OAuth2 客户端的 範圍、授權類型和 重定向 URI。 我們還將提供授權服務器的 授權 URI 和 令牌 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);
}請注意,我們使用 AccessToken 從 OAuth2AuthorizedClient 中檢索了遠程資源 Foo。
8. 結論
在本文中,我們學習瞭如何配置我們的 WebFlux 應用程序以使用 OAuth2 登錄支持,以及如何使用 WebClient 訪問受 OAuth2 保護的資源。