iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0

如果http://a2a-web:80/hello.html這個網頁呼叫http://a2a-web:80/hi.html是可以的,但呼叫http://a2a-api:8081/v1/ap1會被瀏覽器阻擋,這違反瀏覽器預設的同源政策。

URL的組成分別是協議(http、https)、域名(localhost、IP)、port及URI,比如:http:// a2a-web:80/echo,前三者相同就是同源,其中一個不同就觸發CORS(Cross-Origin Resource Sharing,跨來源資源共用)。

事實上瀏覽器發現請求是CORS不是直接擋,流程就像來客到a2a-api公司門口請櫃台窗口通報,櫃台識別來客是a2a-web這家公司是允許名單就讓它呼叫API,不在允許名單裡,瀏覽器就充當警衛的角色請來客走人。

Spring-Security是Spring家族的資安單位,Spring Boot當然直接引用最快。CORS允許清單就設在.container檔,以逗號分隔來源。例:vi .config/containers/systemd/a2a-api.container

[Container]
# 略...
Environment=platform.security.cors.allowed-origins=http://a2a-web:80,https://a2a-proxy:8443

而在Spring Boot專案增加SecurityConfig來讀platform.security.cors.allowed-origins參數。

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.List;

@Configuration
@EnableWebSecurity                          // 1.生效Spring-Security
@ConfigurationProperties(prefix = "platform.security.cors") // 2.讀環境變數
public class SecurityConfig {
    private List<String> allowedOrigins;    // 3. 從環境變數載入來源清單

    private CorsConfigurationSource createCorsConfig() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(allowedOrigins); // 4. 設定允許來源清單
        config.setAllowedHeaders(List.of("*"));
        config.setAllowedMethods(List.of("*"));
        config.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);

        return source;
    }
    
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        return http
                .csrf(csrf -> csrf.disable())
                .httpBasic(Customizer.withDefaults())
                .formLogin(Customizer.withDefaults())
                .authorizeHttpRequests(request -> request
                        .anyRequest().authenticated()
                )
                // 5. 設定CORS生效
                .cors(cors -> cors
                        .configurationSource(createCorsConfig())
                )

                .build();
    }
}
  1. @Confinguration搭@EnableWebSecurity才能讓Spring-Security起作用。
  2. 透過ConfigurationProperties讀名稱是platform.security.cors開頭的環境變數。
  3. allowedOrigins必須是駝峰式命名,這樣以下名稱都符合注入要求的格式。
platform.security.cors.allowed-origins
platform.security.cors.allowedOrigins
  1. 設定CORS允許清單
  2. 生效CORS

上一篇
在Proxy設憑證
下一篇
.container的Unit標籤
系列文
Podman Quadlet-容器服務化(在單體系統到微服務之間)14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言