mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-12-26 01:54:03 +00:00
Test NimbusJwtEncoder & NimbusJwtDecoder symmetrically
This test encodes an JWT with NimbusJwtEncoder, and then decodes it with NimbusJwtDecoder. This test will fail when NimbusJwtEncoder emits a JWT with a wrong `typ' parameter in the header, as NimbusJwtDecoder validates the JWT with JwtTypeValidator by default. It may be beneficial for finding out other similiar bugs too. Signed-off-by: Ziqin Wang <ziqin@wangziqin.net>
This commit is contained in:
parent
dbf93acb05
commit
c8898f91fc
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.oauth2.jwt;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import com.nimbusds.jose.JOSEException;
|
||||
import com.nimbusds.jose.crypto.impl.ECDSA;
|
||||
import com.nimbusds.jose.jwk.Curve;
|
||||
import com.nimbusds.jose.jwk.ECKey;
|
||||
import com.nimbusds.jose.jwk.JWK;
|
||||
import com.nimbusds.jose.jwk.JWKSet;
|
||||
import com.nimbusds.jose.jwk.KeyOperation;
|
||||
import com.nimbusds.jose.jwk.KeyUse;
|
||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Use {@link NimbusJwtDecoder} to decode JWT's encoded with {@link NimbusJwtEncoder}
|
||||
*
|
||||
* @author Ziqin Wang
|
||||
*/
|
||||
public class NimbusJwtEncoderDecoderTests {
|
||||
|
||||
@Test
|
||||
public void encodeAndDecodeHS256() throws GeneralSecurityException {
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256");
|
||||
SecretKey secretKey = keyGenerator.generateKey();
|
||||
|
||||
NimbusJwtEncoder jwtEncoder = NimbusJwtEncoder.withSecretKey(secretKey).build();
|
||||
JwtClaimsSet claims = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
String jwt = jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
|
||||
|
||||
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withSecretKey(secretKey).build();
|
||||
Jwt decodedJwt = jwtDecoder.decode(jwt);
|
||||
|
||||
assertThat(decodedJwt.getSubject()).isEqualTo("subject");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeAndDecodeRS256() throws GeneralSecurityException {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(2048);
|
||||
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
|
||||
NimbusJwtEncoder jwtEncoder = NimbusJwtEncoder.withKeyPair(publicKey, privateKey).build();
|
||||
JwtClaimsSet claims = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
String jwt = jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
|
||||
|
||||
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey(publicKey).build();
|
||||
Jwt decodedJwt = jwtDecoder.decode(jwt);
|
||||
|
||||
assertThat(decodedJwt.getSubject()).isEqualTo("subject");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeAndDecodeES256() throws GeneralSecurityException, JOSEException {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
|
||||
keyPairGenerator.initialize(new ECGenParameterSpec("secp256r1"));
|
||||
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||
ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
|
||||
ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
|
||||
|
||||
NimbusJwtEncoder jwtEncoder = NimbusJwtEncoder.withKeyPair(publicKey, privateKey).build();
|
||||
JwtClaimsSet claims = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
String jwt = jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
|
||||
|
||||
Curve curve = Curve.forECParameterSpec(publicKey.getParams());
|
||||
JWK jwk = new ECKey.Builder(curve, publicKey).keyOperations(Set.of(KeyOperation.VERIFY))
|
||||
.keyUse(KeyUse.SIGNATURE)
|
||||
.algorithm(ECDSA.resolveAlgorithm(curve))
|
||||
.keyIDFromThumbprint()
|
||||
.build();
|
||||
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSource(new ImmutableJWKSet<>(new JWKSet(jwk)))
|
||||
.jwsAlgorithm(Objects.requireNonNull(SignatureAlgorithm.from(jwk.getAlgorithm().getName())))
|
||||
.build();
|
||||
Jwt decodedJwt = jwtDecoder.decode(jwt);
|
||||
|
||||
assertThat(decodedJwt.getSubject()).isEqualTo("subject");
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user