贴标申请,仓储转运

This commit is contained in:
2026-10-08 15:55:47 +08:00
parent e09f8785e1
commit 16d2d9111a
160 changed files with 5704 additions and 4799 deletions
@@ -0,0 +1,94 @@
package com.baiyue.common.security;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import com.sun.net.httpserver.HttpServer;
import org.junit.jupiter.api.Test;
import org.springframework.security.oauth2.jwt.JwtException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
class JwksJwtDecoderAutoConfigurationTest {
@Test
void createsDecoderWhenAuthIsUnavailableButRejectsTokenVerification() throws Exception {
int port;
try (var socket = new ServerSocket(0)) {
port = socket.getLocalPort();
}
var decoder = new JwksJwtDecoderAutoConfiguration().jwksJwtDecoder(
"http://127.0.0.1:" + port + "/jwks", "auth-service", "lastleg-api");
var key = new RSAKeyGenerator(2048).keyID("current").generate();
String token = token(key, "auth-service", "lastleg-api", 120, JWSAlgorithm.RS256);
assertThatThrownBy(() -> decoder.decode(token)).isInstanceOf(JwtException.class);
}
@Test
void fetchesOnFirstVerificationCachesKeysAndRefreshesForRotation() throws Exception {
var current = new RSAKeyGenerator(2048).keyID("current").generate();
var next = new RSAKeyGenerator(2048).keyID("next").generate();
var published = new AtomicReference<>(new JWKSet(current.toPublicJWK()));
var requests = new AtomicInteger();
var server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0);
server.createContext("/jwks", exchange -> {
requests.incrementAndGet();
byte[] body = published.get().toString().getBytes(StandardCharsets.UTF_8);
exchange.getResponseHeaders().add("Content-Type", "application/json");
exchange.sendResponseHeaders(200, body.length);
try (var output = exchange.getResponseBody()) {
output.write(body);
}
});
server.start();
try {
var decoder = new JwksJwtDecoderAutoConfiguration().jwksJwtDecoder(
"http://127.0.0.1:" + server.getAddress().getPort() + "/jwks",
"auth-service", "lastleg-api");
assertThat(requests.get()).isZero();
String valid = token(current, "auth-service", "lastleg-api", 120, JWSAlgorithm.RS256);
assertThat(decoder.decode(valid).getSubject()).isEqualTo("42");
assertThatCode(() -> decoder.decode(valid)).doesNotThrowAnyException();
assertThat(requests.get()).isEqualTo(1);
for (String invalid : new String[]{
token(current, "other", "lastleg-api", 120, JWSAlgorithm.RS256),
token(current, "auth-service", "other", 120, JWSAlgorithm.RS256),
token(current, "auth-service", "lastleg-api", -120, JWSAlgorithm.RS256),
token(current, "auth-service", "lastleg-api", 120, JWSAlgorithm.RS512)}) {
assertThatThrownBy(() -> decoder.decode(invalid)).isInstanceOf(JwtException.class);
}
published.set(new JWKSet(next.toPublicJWK()));
assertThat(decoder.decode(token(next, "auth-service", "lastleg-api", 120,
JWSAlgorithm.RS256)).getSubject()).isEqualTo("42");
assertThat(requests.get()).isEqualTo(2);
} finally {
server.stop(0);
}
}
private String token(RSAKey key, String issuer, String audience, int ttl, JWSAlgorithm algorithm)
throws Exception {
var jwt = new SignedJWT(new JWSHeader.Builder(algorithm).keyID(key.getKeyID()).build(),
new JWTClaimsSet.Builder().subject("42").issuer(issuer).audience(audience)
.issueTime(Date.from(Instant.now().minusSeconds(300)))
.expirationTime(Date.from(Instant.now().plusSeconds(ttl))).build());
jwt.sign(new RSASSASigner(key));
return jwt.serialize();
}
}