知識庫 / Spring / Spring Security RSS 訂閱

OAuth2RestTemplate 入門

Spring Security
HongKong
8
12:17 PM · Dec 06 ,2025

1. 概述

本教程將教您如何使用 Spring <em >OAuth2RestTemplate</em> 發送 OAuth2 REST 調用。

我們將創建一個 Spring Web 應用程序,該應用程序能夠列出 GitHub 帳户的倉庫。

2. Maven 配置

首先,我們需要將 <a href="https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security">spring-boot-starter-security</a><a href="https://mvnrepository.com/artifact/org.springframework.security.oauth.boot/spring-security-oauth2-autoconfigure">spring-security-oauth2-autoconfigure</a> 依賴添加到我們的 <em>pom.xml</em> 文件中。由於我們正在構建一個 Web 應用程序,還需要添加 <a href="https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web">spring-boot-starter-web</a><a href="https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf">spring-boot-starter-thymeleaf</a> 依賴。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
    <version>2.6.8</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

3. OAuth2 屬性

接下來,我們將向我們的 application.properties 文件添加 OAuth 配置,以便連接 GitHub 賬户:

github.client.clientId=[CLIENT_ID]
github.client.clientSecret=[CLIENT_SECRET]
github.client.userAuthorizationUri=https://github.com/login/oauth/authorize
github.client.accessTokenUri=https://github.com/login/oauth/access_token
github.client.clientAuthenticationScheme=form

github.resource.userInfoUri=https://api.github.com/user
github.resource.repoUri=https://api.github.com/user/repos

請注意,我們需要用來自 GitHub OAuth 應用的值替換 [CLIENT_ID][CLIENT_SECRET]。 可以按照 創建 OAuth 應用 指南,在 GitHub 上註冊一個新的應用。

請確保 Authorization 回調 URL 設置為 http://localhost:8080, 這將將 OAuth 流重定向到我們的 Web 應用程序主頁。

4. OAuth2RestTemplate 配置

現在,是時候創建一個安全配置,為我們的應用程序提供 OAuth2 支持。

4.1. SecurityConfig

首先,讓我們創建 Spring 的安全配置:

@Configuration
@EnableOAuth2Client
public class SecurityConfig {
    OAuth2ClientContext oauth2ClientContext;

    public SecurityConfig(OAuth2ClientContext oauth2ClientContext) {
        this.oauth2ClientContext = oauth2ClientContext;
    }

    ...
}

The @EnableOAuth2Client 提供了我們用於創建 OAuth2RestTemplate 的 OAuth2 上下文訪問權限。

4.2. OAuth2RestTemplate Bean

第二步,我們將創建用於我們的 OAuth2RestTemplate 的 Bean:

@Bean
public OAuth2RestTemplate restTemplate() {
    return new OAuth2RestTemplate(githubClient(), oauth2ClientContext);
}

@Bean
@ConfigurationProperties("github.client")
public AuthorizationCodeResourceDetails githubClient() {
    return new AuthorizationCodeResourceDetails();
}

藉助此項,我們使用 OAuth2 屬性和上下文來創建模板實例。

@ConfigurationProperties 註解將所有 github.client 屬性注入到 AuthorizationCodeResourceDetails 實例中。

4.3. 身份驗證過濾器

首先,我們需要一個身份驗證過濾器來處理 OAuth2 流程:

private Filter oauth2ClientFilter() {
    OAuth2ClientAuthenticationProcessingFilter oauth2ClientFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/github");
    OAuth2RestTemplate restTemplate = restTemplate();
    oauth2ClientFilter.setRestTemplate(restTemplate);
    UserInfoTokenServices tokenServices = new UserInfoTokenServices(githubResource().getUserInfoUri(), githubClient().getClientId());
    tokenServices.setRestTemplate(restTemplate);
    oauth2ClientFilter.setTokenServices(tokenServices);
    return oauth2ClientFilter;
}

@Bean
@ConfigurationProperties("github.resource")
public ResourceServerProperties githubResource() {
    return new ResourceServerProperties();
}

在這裏,我們正在指示過濾器在我們的應用程序的 /login/github URL 上啓動 OAuth2 流。

4.4. Spring Security 配置

最後,我們註冊 OAuth2ClientContextFilter 並創建一個 Web 安全配置:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/", "/login**", "/error**")
        .permitAll()
        .anyRequest()
        .authenticated()
        .and()
        .logout()
        .logoutUrl("/logout")
        .logoutSuccessUrl("/")
        .and()
        .addFilterBefore(oauth2ClientFilter(), BasicAuthenticationFilter.class);
    return http.build();
}

@Bean
public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
    FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<>();
    registration.setFilter(filter);
    registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
    return registration;
}

我們對Web應用程序的訪問路徑進行安全保護,並確保OAuth2ClientAuthenticationProcessingFilterBasicAuthenticationFilter 之前已註冊。

5. 使用 OAuth2RestTemplate

OAuth2RestTemplate 的主要目標是減少用於執行基於 OAuth2 的 API 調用所需的代碼量。它基本上滿足了我們應用程序的兩個需求:

  • 處理 OAuth2 身份驗證流程
  • 擴展 Spring 的 RestTemplate 以進行 API 調用

現在,我們可以將 OAuth2RestTemplate 用作 Web 控制器中的自動注入的 Bean。

5.1. 登錄

讓我們創建包含登錄和主頁選項的 index.html 文件:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>OAuth2Client</title>
</head>
<body>
<h3>
    <a href="/login/github" th:href="@{/home}" th:if="${#httpServletRequest?.remoteUser != undefined }">
        Go to Home
    </a>
    <a href="/hello" th:href="@{/login/github}" th:if="${#httpServletRequest?.remoteUser == undefined }">
        GitHub Login
    </a>
</h3>
</body>
</html>

未認證用户將看到登錄選項,而已認證用户可以訪問主頁。

5.2. 主頁

現在,讓我們創建一個控制器來向已認證的 GitHub 用户問候:

@Controller
public class AppController {

    OAuth2RestTemplate restTemplate;

    public AppController(OAuth2RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @GetMapping("/home")
    public String welcome(Model model, Principal principal) {
        model.addAttribute("name", principal.getName());
        return "home";
    }
}

請注意,我們在 welcome 方法中有一個 Principal 參數。我們使用 Principal 的名稱作為 UI 模型的一個屬性。

讓我們來查看 home.html 模板:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Home</title>
</head>
<body>
    <p>
        Welcome <b th:inline="text"> [[${name}]] </b>
    </p>
    <h3>
        <a href="/repos">View Repositories</a><br/><br/>
    </h3>

    <form th:action="@{/logout}" method="POST">
        <input type="submit" value="Logout"/>
    </form>
</body>
</html>

此外,我們還添加了查看用户倉庫列表的鏈接以及登出選項。

5.3. GitHub 倉庫

現在,我們將使用之前創建的 <em>OAuth2RestTemplate</em> 來展示用户擁有的所有 GitHub 倉庫。

首先,我們需要創建一個 <em>GithubRepo</em> 類來表示一個倉庫:

public class GithubRepo {
    Long id;
    String name;

    // getters and setters

}

第二,我們為之前的 AppController 添加一個倉庫映射。

@GetMapping("/repos")
public String repos(Model model) {
    Collection<GithubRepo> repos = restTemplate.getForObject("https://api.github.com/user/repos", Collection.class);
    model.addAttribute("repos", repos);
    return "repositories";
}

OAuth2RestTemplate 會處理所有與向 GitHub 發送請求的樣板代碼。 此外,它會將 REST 響應轉換為 GithubRepo 集合。

最後,讓我們創建一個 repositories.html 模板,以迭代遍歷該集合:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Repositories</title>
</head>
<body>
    <p>
        <h2>Repos</h2>
    </p>
    <ul th:each="repo: ${repos}">
        <li th:text="${repo.name}"></li>
    </ul>
</body>
</html>

6. 結論

在本文中,我們學習瞭如何使用OAuth2RestTemplate來簡化對OAuth2資源服務器的REST調用,例如GitHub。

我們回顧了Web應用程序中OAuth2流程的構建模塊。然後,我們看到了如何通過REST API調用來檢索GitHub用户的所有倉庫。

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

發佈 評論

Some HTML is okay.