Spring Cloud Security 入門指南

Spring Cloud,Spring Security
Remote
0
02:50 AM · Nov 30 ,2025

1. 概述

Spring Cloud Security模塊提供與Spring Boot應用程序中基於令牌的安全性相關的功能。

具體來説,它使基於OAuth2的單點登錄(SSO)更容易——包括在資源服務器之間傳遞令牌的支持,以及使用嵌入的Zuul代理配置下游身份驗證。

在本文中,我們將瞭解如何使用Spring Boot客户端應用程序、授權服務器和作為資源服務器工作的REST API來配置這些功能。

請注意,對於此示例,我們只有一個客户端應用程序使用SSO來演示雲安全功能——但在典型場景中,我們至少需要兩個客户端應用程序來證明單點登錄的需求。

2. 快速啓動雲安全應用

讓我們從配置 Spring Boot 應用程序中的 SSO開始。

首先,我們需要添加 spring-cloud-starter-oauth2依賴項:


<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>

這將同時引入 spring-cloud-starter-security依賴項。

我們可以將任何社交網站配置為我們的網站的身份驗證服務器,或者我們可以使用自己的服務器。 在我們的情況下,我們選擇了後者,並配置了一個作為授權服務器運行的應用程序——它已本地部署在 http://localhost:7070/authserver

我們的授權服務器使用 JWT 令牌。

此外,為了使任何客户端能夠檢索用户的憑據,我們需要配置我們的資源服務器,該服務器在 9000 端口上運行,並配置一個可以提供這些憑據的端點。

在這裏,我們配置了一個 /user端點,該端點可在 http://localhost:9000/user

有關如何設置授權服務器和資源服務器的更多詳細信息,請查看我們的上一篇文章在此處

現在,我們可以將該註釋添加到客户端應用程序中的配置類中:


@Configuration
public class SiteSecurityConfigurer {
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // ...   
        http.oauth2Login();    
        // ... 
    }
}

任何需要身份驗證的請求都將被重定向到授權服務器。為了使此功能正常工作,我們還需要定義服務器屬性:


spring:
  security:
    oauth2:
      client:
        registration:
          baeldung:
            client-id: authserver
            client-secret: authserverpassword
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
        provider:
          baeldung:
            token-uri: http://localhost:7070/authserver/oauth/token
            authorization-uri: http://localhost:7070/authserver/oauth/authorize
            user-info-uri: http://localhost:9000/user

請注意,為了使上述配置正常工作,我們需要在我們的類路徑中包含 spring-boot-starter-security

3. 傳遞訪問令牌在傳遞令牌時,OAuth2 客户端會將由其接收到的 OAuth2 令牌轉發到發出的資源請求。

Spring Security 暴露了一個 OAuth2AuthorizedClientService,這對於創建 RestTemplate 攔截器很有用。根據這一點,我們可以為我們的客户端應用程序創建自己的 RestTemplate

@Bean
public RestOperations restTemplate(OAuth2AuthorizedClientService clientService) {
    return new RestTemplateBuilder().interceptors((ClientHttpRequestInterceptor) 
        (httpRequest, bytes, execution) -> {
        OAuth2AuthenticationToken token = 
        OAuth2AuthenticationToken.class.cast(SecurityContextHolder.getContext()
            .getAuthentication());
        OAuth2AuthorizedClient client = 
            clientService.loadAuthorizedClient(token.getAuthorizedClientRegistrationId(), 
            token.getName());
            httpRequest.getHeaders()
                .add(HttpHeaders.AUTHORIZATION, "Bearer " + client.getAccessToken()
                    .getTokenValue());
        return execution.execute(httpRequest, bytes);
    }).build();
}

一旦我們配置了該 Bean, 上下文將將訪問令牌轉發到請求的服務,並且如果它過期,還會刷新令牌。

4. 使用 RestTemplate 發送 OAuth 令牌

我們之前已經定義了 Client 應用程序中類型的 restOperations 豆。因此,我們可以使用 RestTemplategetForObject() 方法,將必要的令牌發送到受保護的資源服務器

首先,讓我們定義資源服務器中需要身份驗證的端點:

@GetMapping("/person")
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
public @ResponseBody Person personInfo(){
    return new Person("abir", "Dhaka", "Bangladesh", 29, "Male");
}

這是一個簡單的 REST 端點,返回 Person 對象的 JSON 表示形式。

現在,我們可以使用 Client 應用程序中的 getForObject() 方法,通過該方法將令牌發送到資源服務器

@Autowired
private RestOperations restOperations;

@GetMapping("/personInfo")
public ModelAndView person() {
    ModelAndView mav = new ModelAndView("personinfo");
    String personResourceUrl = "http://localhost:9000/person";
    mav.addObject("person",
      restOperations.getForObject(personResourceUrl, String.class));

    return mav;
}

5. 配置 Zuul 用於令牌轉發

如果我們希望將令牌轉發到代理服務,可以使用 Spring Cloud Zuul 內嵌反向代理。

首先,我們需要添加用於與 Zuul 協作的 Maven 依賴項:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

接下來,我們需要在客户端應用程序的配置類上添加 @EnableZuulProxy 註解:

@EnableZuulProxy
@Configuration
public class SiteSecurityConfigurer {
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // ...   
        http.oauth2Login();    
        // ... 
    }
}

剩下的就是將 Zuul 配置屬性添加到我們的 application.yml 文件中:

zuul:
  sensitiveHeaders: Cookie,Set-Cookie  
  routes:
    resource:
      path: /api/**
      url: http://localhost:9000
    user: 
      path: /user/**
      url: http://localhost:9000/user

所有來自客户端應用程序 /api 端點的請求都將被重定向到 Resource Server URL。 我們還需要提供用户憑據端點的 URL。

6. 結論

在本文中,我們探討了如何使用 Spring Cloud Security 與 OAuth2 和 Zuul 結合,配置安全授權和資源服務器,以及如何使用 RestTemplate 在服務器之間傳遞 OAuth2 令牌。

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

發佈 評論

Some HTML is okay.