1. 簡介
在本教程中,我們將探討如何使用 Spring Security 的 OAuth 2.0 支持與 Amazon Cognito 進行身份驗證。
在學習過程中,我們將簡要了解一下 Amazon Cognito 是什麼以及它支持的哪種 OAuth 2.0 流。
最終,我們將擁有一個簡單的單頁應用程序。 沒有任何花哨的東西。
2. 什麼是 Amazon Cognito?
Cognito 是一種用户身份和數據同步服務,它使我們能夠輕鬆管理應用程序的數據,這些應用程序跨多個設備使用。
通過 Amazon Cognito,我們可以:
- 為我們的應用程序創建、驗證和授權用户
- 為使用其他公共 身份提供商(如 Google、Facebook 或 Twitter)的應用程序用户創建身份
- 將應用程序的用户數據保存為鍵值對
3. Setup
3.1. Amazon Cognito Setup
作為身份提供者,Cognito 支持 authorization_code, implicit, 和 client_credentials 授權類型。對於我們的目的,讓我們使用 authorization_code 授權類型進行設置。
首先,我們需要一些 Cognito 設置:
- 創建用户池
- 添加用户 – 我們將使用此用户登錄到我們的 Spring 應用程序
- 創建 App 客户端
- 配置 App 客户端
在應用程序客户端的配置中,請確保 CallbackURL 與 redirect-uri 匹配 Spring 配置文件的 redirect-uri。 在我們的情況下,這將是:
http://localhost:8080/login/oauth2/code/cognito
Allowed OAuth flow 應該是 Authorization code grant. 然後,在同一頁面,我們需要設置 Allowed OAuth scope 為 openid.
為了將用户重定向到 Cognito 的自定義登錄頁面,我們還需要添加 User Pool 域名。
3.2. Spring Setup
由於我們想使用 OAuth 2.0 登錄,我們需要添加 spring-security-oauth2-client 和 spring-security-oauth2-jose 依賴項到我們的應用程序:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
然後,我們需要一些配置來將所有內容綁定在一起:
spring:
security:
oauth2:
client:
registration:
cognito:
clientId: clientId
clientSecret: clientSecret
scope: openid
redirect-uri: http://localhost:8080/login/oauth2/code/cognito
clientName: clientName
provider:
cognito:
issuerUri: https://cognito-idp.{region}.amazonaws.com/{poolId}
user-name-attribute: cognito:username
在上述配置中,屬性 clientId、clientSecret、clientName 和 issuerUri 應根據我們的 User Pool 和 App 客户端 在 AWS 中創建的內容進行填充。
並且有了這些,我們應該已經 Spring 和 Amazon Cognito 設置完畢! 教程的其餘部分定義了應用程序的安全性配置,然後只是將幾個不必要的環節固定下來。
3.3. Spring Security Configuration
現在我們將添加一個安全配置類:
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(Customizer.withDefaults())
.authorizeHttpRequests(authz -> authz.requestMatchers("/")
.permitAll()
.anyRequest()
.authenticated())
.oauth2Login(Customizer.withDefaults())
.logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.logoutSuccessUrl("/"));
return http.build();
}
}
這裏,我們首先指定了需要保護 CSRF 攻擊,然後允許所有用户訪問我們的主頁。之後,我們添加了對 oauth2Login 的調用,以將 Cognito 客户端註冊與一起連接。
4. 添加登陸頁面
接下來,我們添加一個簡單的Thymeleaf登陸頁面,以便我們知道是否已登錄:
<div>
<h1 class="title">OAuth 2.0 Spring Security Cognito Demo</h1>
<div sec:authorize="isAuthenticated()">
<div class="box">
Hello, <strong th:text="${#authentication.name}"></strong>!
</div>
</div>
<div sec:authorize="isAnonymous()">
<div class="box">
<a class="button login is-primary" th:href="@{/oauth2/authorization/cognito}">
使用 Amazon Cognito 登錄</a>
</div>
</div>
</div>
簡單來説,這將顯示我們的用户名,當我們已登錄時,或者當我們未登錄時,將顯示一個登錄鏈接。請仔細查看鏈接的外觀,因為它會從我們的配置文件中獲取 cognito 部分。
然後,讓我們確保將應用程序根目錄與歡迎頁面關聯:
@Configuration
public class CognitoWebConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
}
}
5. 運行應用
該類將啓動與身份驗證相關的所有操作:
@SpringBootApplication
public class SpringCognitoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCognitoApplication.class, args);
}
}
現在我們可以啓動我們的應用程序,前往 http://localhost:8080,然後點擊登錄鏈接。 在輸入我們創建的 AWS 用户憑據後,我們應該能夠看到 Hello, username 消息。
6. 結論
在本教程中,我們探討了如何將 Spring Security 與 Amazon Cognito 集成,只需進行一些簡單的配置。然後,我們用幾行代碼將所有內容整合在一起。