Sebastián Giraldo
01/24/2025, 7:28 PM@RegisterExtension
public final static WireMockExtension wireMockServer = WireMockExtension.newInstance()
.options(wireMockConfig().dynamicPort())
.build();
And setting up a stub for get("/") inside a @BeforeEach method. However the stub only seems to work correctly once and then it stops working. Any help towards fixing it would be appreciatedLee Turner
01/25/2025, 8:26 AMSebastián Giraldo
01/27/2025, 1:18 PMprivate RSAKey rsaKey;
private static final String KEY_ID = "... some random string ...";
@RegisterExtension
public final static WireMockExtension wireMockServer = WireMockExtension.newInstance()
.options(wireMockConfig().dynamicPort())
.configureStaticDsl(true)
.build();
@Value("${spring.security.oauth2.resourceserver.jwt.authority}")
public String AUTHORITY;
protected HttpHeaders httpBasicHeaders;
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.security.oauth2.resourceserver.jwt.jwk-set-uri", wireMockServer::baseUrl);
}
@BeforeEach
public void beforeEach() throws Exception {
MockitoAnnotations.openMocks(
this);
// generate an RSA Key Pair
rsaKey = new RSAKeyGenerator(2048)
.keyUse(KeyUse.SIGNATURE)
.algorithm(new Algorithm("RS256"))
.keyID(KEY_ID)
.generate();
var rsaPublicJWK = rsaKey.toPublicJWK();
var jwkResponse = String.format("{\"keys\": [%s]}", rsaPublicJWK.toJSONString());
// return mock JWK response
wireMockServer.stubFor(WireMock.get("/")
.willReturn(aResponse()
.withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
.withBody(jwkResponse)));
String jwt = getSignedJwt();
// Set the Authorization header
httpBasicHeaders = new HttpHeaders();
httpBasicHeaders.set("Authorization", "Bearer " + jwt);
httpBasicHeaders.setContentType(MediaType.APPLICATION_JSON);
}
protected String getSignedJwt() throws Exception {
var signer = new RSASSASigner(rsaKey);
var claimsSet = new JWTClaimsSet.Builder()
.audience(AUTHORITY.substring(4))
.expirationTime(new Date(new Date().getTime() + 60 * 1000))
.build();
var signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256)
.keyID(rsaKey.getKeyID()).build(), claimsSet);
signedJWT.sign(signer);
return signedJWT.serialize();
}
Here is the whole setup I have for my tests, I'm not really sure what is happening when I stop getting an answer from wireMock, since SpringSecurity is the one actually going to the server to verify the token.
If I run test cases one by one, they all work; If I run the whole gradle task with 6 tests, only the first works; If I run a test class with 2-3 cases, again only the first one works.
From debugging I saw that the stub is being correctly reset, and then configured again for the new RSA key pair; but tests 2...end keep failing with a 401 exceptionLee Turner
01/28/2025, 9:23 AM401
on subsequent tests after the first one passes. I guess this is Spring Security that is throwing the 401
Unauthorised because I don't see anything in your WireMock setup that is configured to return a 401
. Is there a mismatch between what Spring Security is expecting and what WireMock is providing after the first successful test?