知識庫 / Spring / Spring Cloud RSS 訂閱

Spring Cloud Security 入門指南

Spring Cloud,Spring Security
HongKong
9
02:06 PM · Dec 06 ,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: passwordforauthserver
            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 令牌

我們之前在客户端應用程序中定義了一個名為 restOperations 的 Bean,類型為 RestTemplate。因此,我們可以使用 RestTemplategetForObject() 方法,將包含必要的令牌的請求發送到受保護的資源服務器。

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

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

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

現在,我們可以使用 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 內嵌反向代理。

首先,我們需要添加 Maven 依賴項,以便與 Zuul 配合工作:

<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</em lang="en"> 端點接收到的任何請求都將被重定向到資源服務器的 URL。 此外,還需要提供用户憑據端點的 URL。

6. 結論

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

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

發佈 評論

Some HTML is okay.