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-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 開發者控制枱 中創建一個新項目。
現在,我們需要添加 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);
}
注意,我們使用AccessToken從OAuth2AuthorizedClient檢索了遠程資源Foo。
8. 結論
在本文中,我們學習瞭如何配置我們的 WebFlux 應用程序以使用 OAuth2 登錄支持,以及如何使用 WebClient 訪問受 OAuth2 保護的資源。