Replace ManagedKey with CryptoKey
Closes gh-105
This commit is contained in:
@@ -27,8 +27,8 @@ import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
import org.springframework.security.config.test.SpringTestRule;
|
||||
import org.springframework.security.crypto.keys.KeyManager;
|
||||
import org.springframework.security.crypto.keys.StaticKeyGeneratingKeyManager;
|
||||
import org.springframework.security.crypto.key.CryptoKeySource;
|
||||
import org.springframework.security.crypto.key.StaticKeyGeneratingCryptoKeySource;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
@@ -85,7 +85,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
|
||||
private static RegisteredClientRepository registeredClientRepository;
|
||||
private static OAuth2AuthorizationService authorizationService;
|
||||
private static KeyManager keyManager;
|
||||
private static CryptoKeySource keySource;
|
||||
|
||||
@Rule
|
||||
public final SpringTestRule spring = new SpringTestRule();
|
||||
@@ -97,7 +97,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
public static void init() {
|
||||
registeredClientRepository = mock(RegisteredClientRepository.class);
|
||||
authorizationService = mock(OAuth2AuthorizationService.class);
|
||||
keyManager = new StaticKeyGeneratingKeyManager();
|
||||
keySource = new StaticKeyGeneratingCryptoKeySource();
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -266,8 +266,8 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
KeyManager keyManager() {
|
||||
return keyManager;
|
||||
CryptoKeySource keySource() {
|
||||
return keySource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
import org.springframework.security.config.test.SpringTestRule;
|
||||
import org.springframework.security.crypto.keys.KeyManager;
|
||||
import org.springframework.security.crypto.keys.StaticKeyGeneratingKeyManager;
|
||||
import org.springframework.security.crypto.key.CryptoKeySource;
|
||||
import org.springframework.security.crypto.key.StaticKeyGeneratingCryptoKeySource;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
@@ -61,7 +61,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
public class OAuth2ClientCredentialsGrantTests {
|
||||
private static RegisteredClientRepository registeredClientRepository;
|
||||
private static OAuth2AuthorizationService authorizationService;
|
||||
private static KeyManager keyManager;
|
||||
private static CryptoKeySource keySource;
|
||||
|
||||
@Rule
|
||||
public final SpringTestRule spring = new SpringTestRule();
|
||||
@@ -73,7 +73,7 @@ public class OAuth2ClientCredentialsGrantTests {
|
||||
public static void init() {
|
||||
registeredClientRepository = mock(RegisteredClientRepository.class);
|
||||
authorizationService = mock(OAuth2AuthorizationService.class);
|
||||
keyManager = new StaticKeyGeneratingKeyManager();
|
||||
keySource = new StaticKeyGeneratingCryptoKeySource();
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -159,8 +159,8 @@ public class OAuth2ClientCredentialsGrantTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
KeyManager keyManager() {
|
||||
return keyManager;
|
||||
CryptoKeySource keySource() {
|
||||
return keySource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
import org.springframework.security.config.test.SpringTestRule;
|
||||
import org.springframework.security.crypto.keys.KeyManager;
|
||||
import org.springframework.security.crypto.keys.StaticKeyGeneratingKeyManager;
|
||||
import org.springframework.security.crypto.key.CryptoKeySource;
|
||||
import org.springframework.security.crypto.key.StaticKeyGeneratingCryptoKeySource;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
@@ -67,6 +67,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
public class OAuth2RefreshTokenGrantTests {
|
||||
private static RegisteredClientRepository registeredClientRepository;
|
||||
private static OAuth2AuthorizationService authorizationService;
|
||||
private static CryptoKeySource keySource;
|
||||
|
||||
@Rule
|
||||
public final SpringTestRule spring = new SpringTestRule();
|
||||
@@ -78,6 +79,7 @@ public class OAuth2RefreshTokenGrantTests {
|
||||
public static void init() {
|
||||
registeredClientRepository = mock(RegisteredClientRepository.class);
|
||||
authorizationService = mock(OAuth2AuthorizationService.class);
|
||||
keySource = new StaticKeyGeneratingCryptoKeySource();
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -151,6 +153,8 @@ public class OAuth2RefreshTokenGrantTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
KeyManager keyManager() { return new StaticKeyGeneratingKeyManager(); }
|
||||
CryptoKeySource keySource() {
|
||||
return keySource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
|
||||
import org.springframework.security.config.test.SpringTestRule;
|
||||
import org.springframework.security.crypto.keys.KeyManager;
|
||||
import org.springframework.security.crypto.keys.StaticKeyGeneratingKeyManager;
|
||||
import org.springframework.security.crypto.key.CryptoKeySource;
|
||||
import org.springframework.security.crypto.key.StaticKeyGeneratingCryptoKeySource;
|
||||
import org.springframework.security.oauth2.core.AbstractOAuth2Token;
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
|
||||
@@ -66,7 +66,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
public class OAuth2TokenRevocationTests {
|
||||
private static RegisteredClientRepository registeredClientRepository;
|
||||
private static OAuth2AuthorizationService authorizationService;
|
||||
private static KeyManager keyManager;
|
||||
private static CryptoKeySource keySource;
|
||||
|
||||
@Rule
|
||||
public final SpringTestRule spring = new SpringTestRule();
|
||||
@@ -78,7 +78,7 @@ public class OAuth2TokenRevocationTests {
|
||||
public static void init() {
|
||||
registeredClientRepository = mock(RegisteredClientRepository.class);
|
||||
authorizationService = mock(OAuth2AuthorizationService.class);
|
||||
keyManager = new StaticKeyGeneratingKeyManager();
|
||||
keySource = new StaticKeyGeneratingCryptoKeySource();
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -181,8 +181,8 @@ public class OAuth2TokenRevocationTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
KeyManager keyManager() {
|
||||
return keyManager;
|
||||
CryptoKeySource keySource() {
|
||||
return keySource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2020 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.crypto.key;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.KeyPair;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.springframework.security.crypto.key.KeyGeneratorUtils.generateRsaKey;
|
||||
import static org.springframework.security.crypto.key.KeyGeneratorUtils.generateSecretKey;
|
||||
|
||||
/**
|
||||
* Tests for {@link CryptoKey}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class CryptoKeyTests {
|
||||
private static SecretKey secretKey;
|
||||
private static KeyPair rsaKeyPair;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
secretKey = generateSecretKey();
|
||||
rsaKeyPair = generateRsaKey();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void symmetricWhenSecretKeyNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> CryptoKey.symmetric(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("key cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataWhenNameNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> CryptoKey.symmetric(secretKey).metadata(null, "value"))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metadataWhenValueNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> CryptoKey.symmetric(secretKey).metadata("name", null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("value cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void symmetricWhenAllAttributesProvidedThenAllAttributesAreSet() {
|
||||
Map<String, Object> keyMetadata = new HashMap<>();
|
||||
keyMetadata.put("name1", "value1");
|
||||
keyMetadata.put("name2", "value2");
|
||||
|
||||
SymmetricKey symmetricKey = CryptoKey.symmetric(secretKey)
|
||||
.id("id")
|
||||
.metadata(metadata -> metadata.putAll(keyMetadata))
|
||||
.build();
|
||||
|
||||
assertThat(symmetricKey.getKey()).isEqualTo(secretKey);
|
||||
assertThat(symmetricKey.getId()).isEqualTo("id");
|
||||
assertThat(symmetricKey.getMetadata()).isEqualTo(keyMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asymmetricWhenPrivateKeyNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> CryptoKey.asymmetric(null, rsaKeyPair.getPublic()))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("key cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asymmetricWhenPublicKeyNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> CryptoKey.asymmetric(rsaKeyPair.getPrivate(), null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("publicKey cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asymmetricWhenAllAttributesProvidedThenAllAttributesAreSet() {
|
||||
Map<String, Object> keyMetadata = new HashMap<>();
|
||||
keyMetadata.put("name1", "value1");
|
||||
keyMetadata.put("name2", "value2");
|
||||
|
||||
AsymmetricKey asymmetricKey = CryptoKey.asymmetric(rsaKeyPair.getPrivate(), rsaKeyPair.getPublic())
|
||||
.id("id")
|
||||
.metadata(metadata -> metadata.putAll(keyMetadata))
|
||||
.build();
|
||||
|
||||
assertThat(asymmetricKey.getKey()).isEqualTo(rsaKeyPair.getPrivate());
|
||||
assertThat(asymmetricKey.getPublicKey()).isEqualTo(rsaKeyPair.getPublic());
|
||||
assertThat(asymmetricKey.getId()).isEqualTo("id");
|
||||
assertThat(asymmetricKey.getMetadata()).isEqualTo(keyMetadata);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2020 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.crypto.key;
|
||||
|
||||
import java.security.KeyPair;
|
||||
|
||||
import static org.springframework.security.crypto.key.KeyGeneratorUtils.generateEcKey;
|
||||
import static org.springframework.security.crypto.key.KeyGeneratorUtils.generateRsaKey;
|
||||
import static org.springframework.security.crypto.key.KeyGeneratorUtils.generateSecretKey;
|
||||
|
||||
/**
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class TestCryptoKeys {
|
||||
|
||||
public static SymmetricKey.Builder secretKey() {
|
||||
return CryptoKey.symmetric(generateSecretKey());
|
||||
}
|
||||
|
||||
public static AsymmetricKey.Builder rsaKey() {
|
||||
KeyPair rsaKeyPair = generateRsaKey();
|
||||
return CryptoKey.asymmetric(rsaKeyPair.getPrivate(), rsaKeyPair.getPublic());
|
||||
}
|
||||
|
||||
public static AsymmetricKey.Builder ecKey() {
|
||||
KeyPair ecKeyPair = generateEcKey();
|
||||
return CryptoKey.asymmetric(ecKeyPair.getPrivate(), ecKeyPair.getPublic());
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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.crypto.keys;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.Key;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateRsaKey;
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateSecretKey;
|
||||
|
||||
/**
|
||||
* Tests for {@link ManagedKey}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class ManagedKeyTests {
|
||||
private static SecretKey secretKey;
|
||||
private static KeyPair rsaKeyPair;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
secretKey = generateSecretKey();
|
||||
rsaKeyPair = generateRsaKey();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withSymmetricKeyWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withSymmetricKey(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("secretKey cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenKeyIdNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withSymmetricKey(secretKey).build())
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("keyId cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenActivatedOnNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withSymmetricKey(secretKey).keyId("keyId").build())
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("activatedOn cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenSymmetricKeyAllAttributesProvidedThenAllAttributesAreSet() {
|
||||
ManagedKey expectedManagedKey = TestManagedKeys.secretManagedKey().build();
|
||||
|
||||
ManagedKey managedKey = ManagedKey.withSymmetricKey(expectedManagedKey.getKey())
|
||||
.keyId(expectedManagedKey.getKeyId())
|
||||
.activatedOn(expectedManagedKey.getActivatedOn())
|
||||
.build();
|
||||
|
||||
assertThat(managedKey.isSymmetric()).isTrue();
|
||||
assertThat(managedKey.<Key>getKey()).isInstanceOf(SecretKey.class);
|
||||
assertThat(managedKey.<SecretKey>getKey()).isEqualTo(expectedManagedKey.getKey());
|
||||
assertThat(managedKey.getPublicKey()).isNull();
|
||||
assertThat(managedKey.getKeyId()).isEqualTo(expectedManagedKey.getKeyId());
|
||||
assertThat(managedKey.getActivatedOn()).isEqualTo(expectedManagedKey.getActivatedOn());
|
||||
assertThat(managedKey.getDeactivatedOn()).isEqualTo(expectedManagedKey.getDeactivatedOn());
|
||||
assertThat(managedKey.isActive()).isTrue();
|
||||
assertThat(managedKey.getAlgorithm()).isEqualTo(expectedManagedKey.getAlgorithm());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withAsymmetricKeyWhenPublicKeyNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withAsymmetricKey(null, rsaKeyPair.getPrivate()))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("publicKey cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withAsymmetricKeyWhenPrivateKeyNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withAsymmetricKey(rsaKeyPair.getPublic(), null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("privateKey cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenAsymmetricKeyAllAttributesProvidedThenAllAttributesAreSet() {
|
||||
ManagedKey expectedManagedKey = TestManagedKeys.rsaManagedKey().build();
|
||||
|
||||
ManagedKey managedKey = ManagedKey.withAsymmetricKey(expectedManagedKey.getPublicKey(), expectedManagedKey.getKey())
|
||||
.keyId(expectedManagedKey.getKeyId())
|
||||
.activatedOn(expectedManagedKey.getActivatedOn())
|
||||
.build();
|
||||
|
||||
assertThat(managedKey.isAsymmetric()).isTrue();
|
||||
assertThat(managedKey.<Key>getKey()).isInstanceOf(PrivateKey.class);
|
||||
assertThat(managedKey.<PrivateKey>getKey()).isEqualTo(expectedManagedKey.getKey());
|
||||
assertThat(managedKey.getPublicKey()).isNotNull();
|
||||
assertThat(managedKey.getKeyId()).isEqualTo(expectedManagedKey.getKeyId());
|
||||
assertThat(managedKey.getActivatedOn()).isEqualTo(expectedManagedKey.getActivatedOn());
|
||||
assertThat(managedKey.getDeactivatedOn()).isEqualTo(expectedManagedKey.getDeactivatedOn());
|
||||
assertThat(managedKey.isActive()).isTrue();
|
||||
assertThat(managedKey.getAlgorithm()).isEqualTo(expectedManagedKey.getAlgorithm());
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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.crypto.keys;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateEcKey;
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateRsaKey;
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateSecretKey;
|
||||
|
||||
/**
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class TestManagedKeys {
|
||||
|
||||
public static ManagedKey.Builder secretManagedKey() {
|
||||
return ManagedKey.withSymmetricKey(generateSecretKey())
|
||||
.keyId(UUID.randomUUID().toString())
|
||||
.activatedOn(Instant.now());
|
||||
}
|
||||
|
||||
public static ManagedKey.Builder rsaManagedKey() {
|
||||
KeyPair rsaKeyPair = generateRsaKey();
|
||||
return ManagedKey.withAsymmetricKey(rsaKeyPair.getPublic(), rsaKeyPair.getPrivate())
|
||||
.keyId(UUID.randomUUID().toString())
|
||||
.activatedOn(Instant.now());
|
||||
}
|
||||
|
||||
public static ManagedKey.Builder ecManagedKey() {
|
||||
KeyPair ecKeyPair = generateEcKey();
|
||||
return ManagedKey.withAsymmetricKey(ecKeyPair.getPublic(), ecKeyPair.getPrivate())
|
||||
.keyId(UUID.randomUUID().toString())
|
||||
.activatedOn(Instant.now());
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,9 @@ package org.springframework.security.oauth2.jose.jws;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.crypto.keys.KeyManager;
|
||||
import org.springframework.security.crypto.keys.ManagedKey;
|
||||
import org.springframework.security.crypto.keys.TestManagedKeys;
|
||||
import org.springframework.security.crypto.key.AsymmetricKey;
|
||||
import org.springframework.security.crypto.key.CryptoKeySource;
|
||||
import org.springframework.security.crypto.key.TestCryptoKeys;
|
||||
import org.springframework.security.oauth2.jose.JoseHeader;
|
||||
import org.springframework.security.oauth2.jose.JoseHeaderNames;
|
||||
import org.springframework.security.oauth2.jose.TestJoseHeaders;
|
||||
@@ -30,14 +30,12 @@ import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.TestJwtClaimsSets;
|
||||
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -47,20 +45,20 @@ import static org.mockito.Mockito.when;
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class NimbusJwsEncoderTests {
|
||||
private KeyManager keyManager;
|
||||
private CryptoKeySource keySource;
|
||||
private NimbusJwsEncoder jwtEncoder;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.keyManager = mock(KeyManager.class);
|
||||
this.jwtEncoder = new NimbusJwsEncoder(this.keyManager);
|
||||
this.keySource = mock(CryptoKeySource.class);
|
||||
this.jwtEncoder = new NimbusJwsEncoder(this.keySource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenKeyManagerNullThenThrowIllegalArgumentException() {
|
||||
public void constructorWhenKeySourceNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new NimbusJwsEncoder(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("keyManager cannot be null");
|
||||
.hasMessage("keySource cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,8 +101,8 @@ public class NimbusJwsEncoderTests {
|
||||
|
||||
@Test
|
||||
public void encodeWhenUnsupportedKeyTypeThenThrowJwtEncodingException() {
|
||||
ManagedKey managedKey = TestManagedKeys.ecManagedKey().build();
|
||||
when(this.keyManager.findByAlgorithm(any())).thenReturn(Collections.singleton(managedKey));
|
||||
AsymmetricKey ecKey = TestCryptoKeys.ecKey().build();
|
||||
when(this.keySource.getKeys()).thenReturn(Collections.singleton(ecKey));
|
||||
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader(SignatureAlgorithm.ES256).build();
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
@@ -116,8 +114,8 @@ public class NimbusJwsEncoderTests {
|
||||
|
||||
@Test
|
||||
public void encodeWhenSuccessThenDecodes() {
|
||||
ManagedKey managedKey = TestManagedKeys.rsaManagedKey().build();
|
||||
when(this.keyManager.findByAlgorithm(any())).thenReturn(Collections.singleton(managedKey));
|
||||
AsymmetricKey rsaKey = TestCryptoKeys.rsaKey().build();
|
||||
when(this.keySource.getKeys()).thenReturn(Collections.singleton(rsaKey));
|
||||
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader()
|
||||
.headers(headers -> headers.remove(JoseHeaderNames.CRIT))
|
||||
@@ -126,25 +124,17 @@ public class NimbusJwsEncoderTests {
|
||||
|
||||
Jwt jws = this.jwtEncoder.encode(joseHeader, jwtClaimsSet);
|
||||
|
||||
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey((RSAPublicKey) managedKey.getPublicKey()).build();
|
||||
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey((RSAPublicKey) rsaKey.getPublicKey()).build();
|
||||
jwtDecoder.decode(jws.getTokenValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWhenMultipleActiveKeysThenUseMostRecent() {
|
||||
ManagedKey managedKeyActivated2DaysAgo = TestManagedKeys.rsaManagedKey()
|
||||
.activatedOn(Instant.now().minus(2, ChronoUnit.DAYS))
|
||||
.build();
|
||||
ManagedKey managedKeyActivated1DayAgo = TestManagedKeys.rsaManagedKey()
|
||||
.activatedOn(Instant.now().minus(1, ChronoUnit.DAYS))
|
||||
.build();
|
||||
ManagedKey managedKeyActivatedToday = TestManagedKeys.rsaManagedKey()
|
||||
.activatedOn(Instant.now())
|
||||
.build();
|
||||
|
||||
when(this.keyManager.findByAlgorithm(any())).thenReturn(
|
||||
Stream.of(managedKeyActivated2DaysAgo, managedKeyActivated1DayAgo, managedKeyActivatedToday)
|
||||
.collect(Collectors.toSet()));
|
||||
public void encodeWhenMultipleActiveKeysThenUseFirst() {
|
||||
AsymmetricKey rsaKey1 = TestCryptoKeys.rsaKey().build();
|
||||
AsymmetricKey rsaKey2 = TestCryptoKeys.rsaKey().build();
|
||||
when(this.keySource.getKeys()).thenReturn(
|
||||
Stream.of(rsaKey1, rsaKey2)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new)));
|
||||
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader()
|
||||
.headers(headers -> headers.remove(JoseHeaderNames.CRIT))
|
||||
@@ -153,7 +143,7 @@ public class NimbusJwsEncoderTests {
|
||||
|
||||
Jwt jws = this.jwtEncoder.encode(joseHeader, jwtClaimsSet);
|
||||
|
||||
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey((RSAPublicKey) managedKeyActivatedToday.getPublicKey()).build();
|
||||
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey((RSAPublicKey) rsaKey1.getPublicKey()).build();
|
||||
jwtDecoder.decode(jws.getTokenValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,14 +25,14 @@ import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.crypto.keys.KeyManager;
|
||||
import org.springframework.security.crypto.keys.ManagedKey;
|
||||
import org.springframework.security.crypto.keys.TestManagedKeys;
|
||||
import org.springframework.security.crypto.key.AsymmetricKey;
|
||||
import org.springframework.security.crypto.key.CryptoKeySource;
|
||||
import org.springframework.security.crypto.key.SymmetricKey;
|
||||
import org.springframework.security.crypto.key.TestCryptoKeys;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -52,25 +52,25 @@ import static org.mockito.Mockito.when;
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class JwkSetEndpointFilterTests {
|
||||
private KeyManager keyManager;
|
||||
private CryptoKeySource keySource;
|
||||
private JwkSetEndpointFilter filter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.keyManager = mock(KeyManager.class);
|
||||
this.filter = new JwkSetEndpointFilter(this.keyManager);
|
||||
this.keySource = mock(CryptoKeySource.class);
|
||||
this.filter = new JwkSetEndpointFilter(this.keySource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenKeyManagerNullThenThrowIllegalArgumentException() {
|
||||
public void constructorWhenKeySourceNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new JwkSetEndpointFilter(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("keyManager cannot be null");
|
||||
.hasMessage("keySource cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenJwkSetEndpointUriNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new JwkSetEndpointFilter(this.keyManager, null))
|
||||
assertThatThrownBy(() -> new JwkSetEndpointFilter(this.keySource, null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("jwkSetEndpointUri cannot be empty");
|
||||
}
|
||||
@@ -103,10 +103,10 @@ public class JwkSetEndpointFilterTests {
|
||||
|
||||
@Test
|
||||
public void doFilterWhenAsymmetricKeysThenJwkSetResponse() throws Exception {
|
||||
ManagedKey rsaManagedKey = TestManagedKeys.rsaManagedKey().build();
|
||||
ManagedKey ecManagedKey = TestManagedKeys.ecManagedKey().build();
|
||||
when(this.keyManager.getKeys()).thenReturn(
|
||||
Stream.of(rsaManagedKey, ecManagedKey).collect(Collectors.toSet()));
|
||||
AsymmetricKey rsaKey = TestCryptoKeys.rsaKey().build();
|
||||
AsymmetricKey ecKey = TestCryptoKeys.ecKey().build();
|
||||
when(this.keySource.getKeys()).thenReturn(
|
||||
Stream.of(rsaKey, ecKey).collect(Collectors.toSet()));
|
||||
|
||||
String requestUri = JwkSetEndpointFilter.DEFAULT_JWK_SET_ENDPOINT_URI;
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
||||
@@ -123,17 +123,17 @@ public class JwkSetEndpointFilterTests {
|
||||
JWKSet jwkSet = JWKSet.parse(response.getContentAsString());
|
||||
assertThat(jwkSet.getKeys()).hasSize(2);
|
||||
|
||||
RSAKey rsaJwk = (RSAKey) jwkSet.getKeyByKeyId(rsaManagedKey.getKeyId());
|
||||
RSAKey rsaJwk = (RSAKey) jwkSet.getKeyByKeyId(rsaKey.getId());
|
||||
assertThat(rsaJwk).isNotNull();
|
||||
assertThat(rsaJwk.toRSAPublicKey()).isEqualTo(rsaManagedKey.getPublicKey());
|
||||
assertThat(rsaJwk.toRSAPublicKey()).isEqualTo(rsaKey.getPublicKey());
|
||||
assertThat(rsaJwk.toRSAPrivateKey()).isNull();
|
||||
assertThat(rsaJwk.getKeyUse()).isEqualTo(KeyUse.SIGNATURE);
|
||||
assertThat(rsaJwk.getAlgorithm()).isEqualTo(JWSAlgorithm.RS256);
|
||||
|
||||
ECKey ecJwk = (ECKey) jwkSet.getKeyByKeyId(ecManagedKey.getKeyId());
|
||||
ECKey ecJwk = (ECKey) jwkSet.getKeyByKeyId(ecKey.getId());
|
||||
assertThat(ecJwk).isNotNull();
|
||||
assertThat(ecJwk.toECPublicKey()).isEqualTo(ecManagedKey.getPublicKey());
|
||||
assertThat(ecJwk.toECPublicKey()).isEqualTo(ecManagedKey.getPublicKey());
|
||||
assertThat(ecJwk.toECPublicKey()).isEqualTo(ecKey.getPublicKey());
|
||||
assertThat(ecJwk.toECPublicKey()).isEqualTo(ecKey.getPublicKey());
|
||||
assertThat(ecJwk.toECPrivateKey()).isNull();
|
||||
assertThat(ecJwk.getKeyUse()).isEqualTo(KeyUse.SIGNATURE);
|
||||
assertThat(ecJwk.getAlgorithm()).isEqualTo(JWSAlgorithm.ES256);
|
||||
@@ -141,32 +141,9 @@ public class JwkSetEndpointFilterTests {
|
||||
|
||||
@Test
|
||||
public void doFilterWhenSymmetricKeysThenJwkSetResponseEmpty() throws Exception {
|
||||
ManagedKey secretManagedKey = TestManagedKeys.secretManagedKey().build();
|
||||
when(this.keyManager.getKeys()).thenReturn(
|
||||
new HashSet<>(Collections.singleton(secretManagedKey)));
|
||||
|
||||
String requestUri = JwkSetEndpointFilter.DEFAULT_JWK_SET_ENDPOINT_URI;
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
||||
request.setServletPath(requestUri);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
FilterChain filterChain = mock(FilterChain.class);
|
||||
|
||||
this.filter.doFilter(request, response, filterChain);
|
||||
|
||||
verifyNoInteractions(filterChain);
|
||||
|
||||
assertThat(response.getContentType()).isEqualTo(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
JWKSet jwkSet = JWKSet.parse(response.getContentAsString());
|
||||
assertThat(jwkSet.getKeys()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterWhenNoActiveKeysThenJwkSetResponseEmpty() throws Exception {
|
||||
ManagedKey rsaManagedKey = TestManagedKeys.rsaManagedKey().deactivatedOn(Instant.now()).build();
|
||||
ManagedKey ecManagedKey = TestManagedKeys.ecManagedKey().deactivatedOn(Instant.now()).build();
|
||||
when(this.keyManager.getKeys()).thenReturn(
|
||||
Stream.of(rsaManagedKey, ecManagedKey).collect(Collectors.toSet()));
|
||||
SymmetricKey secretKey = TestCryptoKeys.secretKey().build();
|
||||
when(this.keySource.getKeys()).thenReturn(
|
||||
new HashSet<>(Collections.singleton(secretKey)));
|
||||
|
||||
String requestUri = JwkSetEndpointFilter.DEFAULT_JWK_SET_ENDPOINT_URI;
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
||||
|
||||
Reference in New Issue
Block a user