贴标申请,仓储转运
This commit is contained in:
+94
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user