forked from baskbuddy/zhangshun
2 changed files with 78 additions and 1 deletions
@ -0,0 +1,76 @@ |
|||||
|
package com.mydreamjob.config; |
||||
|
|
||||
|
import org.junit.jupiter.api.Test; |
||||
|
import org.junit.jupiter.params.ParameterizedTest; |
||||
|
import org.junit.jupiter.params.provider.ValueSource; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; |
||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||
|
import org.springframework.boot.test.mock.mockito.MockBean; |
||||
|
import org.springframework.data.redis.core.RedisTemplate; |
||||
|
import org.springframework.test.context.ActiveProfiles; |
||||
|
import org.springframework.test.web.servlet.MockMvc; |
||||
|
|
||||
|
import static org.hamcrest.Matchers.containsString; |
||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; |
||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options; |
||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; |
||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||
|
|
||||
|
@SpringBootTest(properties = { |
||||
|
"spring.datasource.url=jdbc:h2:mem:cors_context_path;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE", |
||||
|
"spring.jpa.show-sql=false", |
||||
|
"app.cors.allowed-origins=http://localhost:5173,http://localhost:3000" |
||||
|
}) |
||||
|
@AutoConfigureMockMvc |
||||
|
@ActiveProfiles("integration-test") |
||||
|
class CorsContextPathIntegrationTest { |
||||
|
@Autowired MockMvc mvc; |
||||
|
@MockBean RedisTemplate<String, Object> redis; |
||||
|
|
||||
|
@ParameterizedTest |
||||
|
@ValueSource(strings = {"http://localhost:5173", "http://localhost:3000"}) |
||||
|
void configuredOriginCanPreflightIdentitySelectionWithApplicationContext(String origin) throws Exception { |
||||
|
mvc.perform(options("/api/v1/auth/identity/select") |
||||
|
.contextPath("/api/v1").servletPath("/auth/identity/select") |
||||
|
.header("Origin", origin) |
||||
|
.header("Access-Control-Request-Method", "POST") |
||||
|
.header("Access-Control-Request-Headers", "authorization,content-type")) |
||||
|
.andExpect(status().isOk()) |
||||
|
.andExpect(header().string("Access-Control-Allow-Origin", origin)) |
||||
|
.andExpect(header().string("Access-Control-Allow-Credentials", "true")) |
||||
|
.andExpect(header().string("Access-Control-Allow-Methods", containsString("POST"))) |
||||
|
.andExpect(header().string("Access-Control-Allow-Headers", containsString("authorization"))); |
||||
|
} |
||||
|
|
||||
|
@ParameterizedTest |
||||
|
@ValueSource(strings = {"http://localhost:5173", "http://localhost:3000"}) |
||||
|
void configuredOriginCanRead401WithoutBypassingAuthentication(String origin) throws Exception { |
||||
|
mvc.perform(get("/api/v1/auth/me") |
||||
|
.contextPath("/api/v1").servletPath("/auth/me") |
||||
|
.header("Origin", origin)) |
||||
|
.andExpect(status().isUnauthorized()) |
||||
|
.andExpect(header().string("Access-Control-Allow-Origin", origin)); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
void unconfiguredOriginRemainsRejected() throws Exception { |
||||
|
mvc.perform(options("/api/v1/auth/identity/select") |
||||
|
.contextPath("/api/v1").servletPath("/auth/identity/select") |
||||
|
.header("Origin", "https://untrusted.example") |
||||
|
.header("Access-Control-Request-Method", "POST")) |
||||
|
.andExpect(status().isForbidden()) |
||||
|
.andExpect(header().doesNotExist("Access-Control-Allow-Origin")); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
void unconfiguredHeaderRemainsRejected() throws Exception { |
||||
|
mvc.perform(options("/api/v1/auth/identity/select") |
||||
|
.contextPath("/api/v1").servletPath("/auth/identity/select") |
||||
|
.header("Origin", "http://localhost:5173") |
||||
|
.header("Access-Control-Request-Method", "POST") |
||||
|
.header("Access-Control-Request-Headers", "x-unapproved-header")) |
||||
|
.andExpect(status().isForbidden()) |
||||
|
.andExpect(header().doesNotExist("Access-Control-Allow-Origin")); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue