Remove JwtEncoder and associated classes
Issue gh-596 Closes gh-724
This commit is contained in:
@@ -81,7 +81,7 @@ import org.springframework.security.oauth2.jose.TestJwks;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwsEncoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService;
|
||||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
|
||||
@@ -161,7 +161,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
|
||||
private static EmbeddedDatabase db;
|
||||
private static JWKSource<SecurityContext> jwkSource;
|
||||
private static NimbusJwsEncoder jwtEncoder;
|
||||
private static NimbusJwtEncoder jwtEncoder;
|
||||
private static ProviderSettings providerSettings;
|
||||
private static HttpMessageConverter<OAuth2AccessTokenResponse> accessTokenHttpResponseConverter =
|
||||
new OAuth2AccessTokenResponseHttpMessageConverter();
|
||||
@@ -197,7 +197,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
public static void init() {
|
||||
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
|
||||
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
jwtEncoder = new NimbusJwsEncoder(jwkSource);
|
||||
jwtEncoder = new NimbusJwtEncoder(jwkSource);
|
||||
providerSettings = ProviderSettings.builder()
|
||||
.authorizationEndpoint("/test/authorize")
|
||||
.tokenEndpoint("/test/token")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2021 the original author or authors.
|
||||
* Copyright 2020-2022 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.
|
||||
@@ -64,12 +64,13 @@ import org.springframework.security.oauth2.core.oidc.OidcClientRegistration;
|
||||
import org.springframework.security.oauth2.core.oidc.http.converter.OidcClientRegistrationHttpMessageConverter;
|
||||
import org.springframework.security.oauth2.jose.TestJwks;
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.JoseHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwsHeader;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwsEncoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
|
||||
@@ -135,7 +136,7 @@ public class OidcClientRegistrationTests {
|
||||
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
|
||||
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
clientJwkSet = new JWKSet(TestJwks.generateRsaJwk().build());
|
||||
jwtClientAssertionEncoder = new NimbusJwsEncoder((jwkSelector, securityContext) -> jwkSelector.select(clientJwkSet));
|
||||
jwtClientAssertionEncoder = new NimbusJwtEncoder((jwkSelector, securityContext) -> jwkSelector.select(clientJwkSet));
|
||||
db = new EmbeddedDatabaseBuilder()
|
||||
.generateUniqueName(true)
|
||||
.setType(EmbeddedDatabaseType.HSQL)
|
||||
@@ -280,12 +281,12 @@ public class OidcClientRegistrationTests {
|
||||
this.registeredClientRepository.save(clientRegistrar);
|
||||
|
||||
// @formatter:off
|
||||
JoseHeader joseHeader = JoseHeader.withAlgorithm(SignatureAlgorithm.RS256)
|
||||
JwsHeader jwsHeader = JwsHeader.with(SignatureAlgorithm.RS256)
|
||||
.build();
|
||||
JwtClaimsSet jwtClaimsSet = jwtClientAssertionClaims(clientRegistrar)
|
||||
.build();
|
||||
// @formatter:on
|
||||
Jwt jwtAssertion = jwtClientAssertionEncoder.encode(joseHeader, jwtClaimsSet);
|
||||
Jwt jwtAssertion = jwtClientAssertionEncoder.encode(JwtEncoderParameters.from(jwsHeader, jwtClaimsSet));
|
||||
|
||||
MvcResult mvcResult = this.mvc.perform(post(DEFAULT_TOKEN_ENDPOINT_URI)
|
||||
.param(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
|
||||
|
||||
@@ -69,17 +69,13 @@ import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames
|
||||
import org.springframework.security.oauth2.jose.TestJwks;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwsEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.JwtEncodingContext;
|
||||
import org.springframework.security.oauth2.server.authorization.token.JwtGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2TokenContext;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
|
||||
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
|
||||
@@ -88,6 +84,10 @@ import org.springframework.security.oauth2.server.authorization.client.Registere
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin;
|
||||
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.JwtGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
@@ -415,7 +415,7 @@ public class OidcTests {
|
||||
|
||||
@Bean
|
||||
OAuth2TokenGenerator<?> tokenGenerator() {
|
||||
JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwsEncoder(jwkSource()));
|
||||
JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource()));
|
||||
jwtGenerator.setJwtCustomizer(jwtCustomizer());
|
||||
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
|
||||
OAuth2TokenGenerator<OAuth2Token> delegatingTokenGenerator =
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2021 the original author or authors.
|
||||
* Copyright 2020-2022 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.
|
||||
@@ -45,12 +45,13 @@ import org.springframework.security.oauth2.core.oidc.OidcScopes;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
|
||||
import org.springframework.security.oauth2.jose.TestJwks;
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.JoseHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwsHeader;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwsEncoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
@@ -207,13 +208,13 @@ public class OidcUserInfoTests {
|
||||
}
|
||||
|
||||
private OAuth2Authorization createAuthorization() {
|
||||
JoseHeader headers = JoseHeader.withAlgorithm(SignatureAlgorithm.RS256).build();
|
||||
JwsHeader headers = JwsHeader.with(SignatureAlgorithm.RS256).build();
|
||||
// @formatter:off
|
||||
JwtClaimsSet claimSet = JwtClaimsSet.builder()
|
||||
.claims(claims -> claims.putAll(createUserInfo().getClaims()))
|
||||
.build();
|
||||
// @formatter:on
|
||||
Jwt jwt = this.jwtEncoder.encode(headers, claimSet);
|
||||
Jwt jwt = this.jwtEncoder.encode(JwtEncoderParameters.from(headers, claimSet));
|
||||
|
||||
Instant now = Instant.now();
|
||||
Set<String> scopes = new HashSet<>(Arrays.asList(
|
||||
@@ -371,7 +372,7 @@ public class OidcUserInfoTests {
|
||||
|
||||
@Bean
|
||||
JwtEncoder jwtEncoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return new NimbusJwsEncoder(jwkSource);
|
||||
return new NimbusJwtEncoder(jwkSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020-2021 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 org.junit.Test;
|
||||
|
||||
import org.springframework.security.oauth2.jose.JwaAlgorithm;
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Tests for {@link JoseHeader}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class JoseHeaderTests {
|
||||
|
||||
@Test
|
||||
public void withAlgorithmWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> JoseHeader.withAlgorithm(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("jwaAlgorithm cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenAllHeadersProvidedThenAllHeadersAreSet() {
|
||||
JoseHeader expectedJoseHeader = TestJoseHeaders.joseHeader().build();
|
||||
|
||||
JoseHeader joseHeader = JoseHeader.withAlgorithm(expectedJoseHeader.getAlgorithm())
|
||||
.jwkSetUrl(expectedJoseHeader.getJwkSetUrl().toExternalForm())
|
||||
.jwk(expectedJoseHeader.getJwk())
|
||||
.keyId(expectedJoseHeader.getKeyId())
|
||||
.x509Url(expectedJoseHeader.getX509Url().toExternalForm())
|
||||
.x509CertificateChain(expectedJoseHeader.getX509CertificateChain())
|
||||
.x509SHA1Thumbprint(expectedJoseHeader.getX509SHA1Thumbprint())
|
||||
.x509SHA256Thumbprint(expectedJoseHeader.getX509SHA256Thumbprint())
|
||||
.type(expectedJoseHeader.getType())
|
||||
.contentType(expectedJoseHeader.getContentType())
|
||||
.headers(headers -> headers.put("custom-header-name", "custom-header-value"))
|
||||
.build();
|
||||
|
||||
assertThat(joseHeader.<JwaAlgorithm>getAlgorithm()).isEqualTo(expectedJoseHeader.getAlgorithm());
|
||||
assertThat(joseHeader.getJwkSetUrl()).isEqualTo(expectedJoseHeader.getJwkSetUrl());
|
||||
assertThat(joseHeader.getJwk()).isEqualTo(expectedJoseHeader.getJwk());
|
||||
assertThat(joseHeader.getKeyId()).isEqualTo(expectedJoseHeader.getKeyId());
|
||||
assertThat(joseHeader.getX509Url()).isEqualTo(expectedJoseHeader.getX509Url());
|
||||
assertThat(joseHeader.getX509CertificateChain()).isEqualTo(expectedJoseHeader.getX509CertificateChain());
|
||||
assertThat(joseHeader.getX509SHA1Thumbprint()).isEqualTo(expectedJoseHeader.getX509SHA1Thumbprint());
|
||||
assertThat(joseHeader.getX509SHA256Thumbprint()).isEqualTo(expectedJoseHeader.getX509SHA256Thumbprint());
|
||||
assertThat(joseHeader.getCritical()).isEqualTo(expectedJoseHeader.getCritical());
|
||||
assertThat(joseHeader.getType()).isEqualTo(expectedJoseHeader.getType());
|
||||
assertThat(joseHeader.getContentType()).isEqualTo(expectedJoseHeader.getContentType());
|
||||
assertThat(joseHeader.<String>getHeader("custom-header-name")).isEqualTo("custom-header-value");
|
||||
assertThat(joseHeader.getHeaders()).isEqualTo(expectedJoseHeader.getHeaders());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> JoseHeader.from(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("headers cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromWhenHeadersProvidedThenCopied() {
|
||||
JoseHeader expectedJoseHeader = TestJoseHeaders.joseHeader().build();
|
||||
JoseHeader joseHeader = JoseHeader.from(expectedJoseHeader).build();
|
||||
assertThat(joseHeader.getHeaders()).isEqualTo(expectedJoseHeader.getHeaders());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerWhenNameNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> JoseHeader.withAlgorithm(SignatureAlgorithm.RS256).header(null, "value"))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerWhenValueNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> JoseHeader.withAlgorithm(SignatureAlgorithm.RS256).header("name", null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("value cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHeaderWhenNullThenThrowIllegalArgumentException() {
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader().build();
|
||||
|
||||
assertThatThrownBy(() -> joseHeader.getHeader(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be empty");
|
||||
}
|
||||
}
|
||||
@@ -1,90 +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.oauth2.jwt;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Tests for {@link JwtClaimsSet}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class JwtClaimsSetTests {
|
||||
|
||||
@Test
|
||||
public void buildWhenClaimsEmptyThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> JwtClaimsSet.builder().build())
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("claims cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenAllClaimsProvidedThenAllClaimsAreSet() {
|
||||
JwtClaimsSet expectedJwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
|
||||
JwtClaimsSet jwtClaimsSet = JwtClaimsSet.builder()
|
||||
.issuer(expectedJwtClaimsSet.getIssuer().toExternalForm())
|
||||
.subject(expectedJwtClaimsSet.getSubject())
|
||||
.audience(expectedJwtClaimsSet.getAudience())
|
||||
.issuedAt(expectedJwtClaimsSet.getIssuedAt())
|
||||
.notBefore(expectedJwtClaimsSet.getNotBefore())
|
||||
.expiresAt(expectedJwtClaimsSet.getExpiresAt())
|
||||
.id(expectedJwtClaimsSet.getId())
|
||||
.claims(claims -> claims.put("custom-claim-name", "custom-claim-value"))
|
||||
.build();
|
||||
|
||||
assertThat(jwtClaimsSet.getIssuer()).isEqualTo(expectedJwtClaimsSet.getIssuer());
|
||||
assertThat(jwtClaimsSet.getSubject()).isEqualTo(expectedJwtClaimsSet.getSubject());
|
||||
assertThat(jwtClaimsSet.getAudience()).isEqualTo(expectedJwtClaimsSet.getAudience());
|
||||
assertThat(jwtClaimsSet.getIssuedAt()).isEqualTo(expectedJwtClaimsSet.getIssuedAt());
|
||||
assertThat(jwtClaimsSet.getNotBefore()).isEqualTo(expectedJwtClaimsSet.getNotBefore());
|
||||
assertThat(jwtClaimsSet.getExpiresAt()).isEqualTo(expectedJwtClaimsSet.getExpiresAt());
|
||||
assertThat(jwtClaimsSet.getId()).isEqualTo(expectedJwtClaimsSet.getId());
|
||||
assertThat(jwtClaimsSet.<String>getClaim("custom-claim-name")).isEqualTo("custom-claim-value");
|
||||
assertThat(jwtClaimsSet.getClaims()).isEqualTo(expectedJwtClaimsSet.getClaims());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> JwtClaimsSet.from(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("claims cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromWhenClaimsProvidedThenCopied() {
|
||||
JwtClaimsSet expectedJwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
JwtClaimsSet jwtClaimsSet = JwtClaimsSet.from(expectedJwtClaimsSet).build();
|
||||
assertThat(jwtClaimsSet.getClaims()).isEqualTo(expectedJwtClaimsSet.getClaims());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void claimWhenNameNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> JwtClaimsSet.builder().claim(null, "value"))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void claimWhenValueNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> JwtClaimsSet.builder().claim("name", null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("value cannot be null");
|
||||
}
|
||||
}
|
||||
@@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020-2021 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.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.nimbusds.jose.KeySourceException;
|
||||
import com.nimbusds.jose.jwk.ECKey;
|
||||
import com.nimbusds.jose.jwk.JWK;
|
||||
import com.nimbusds.jose.jwk.JWKSelector;
|
||||
import com.nimbusds.jose.jwk.JWKSet;
|
||||
import com.nimbusds.jose.jwk.KeyUse;
|
||||
import com.nimbusds.jose.jwk.OctetSequenceKey;
|
||||
import com.nimbusds.jose.jwk.RSAKey;
|
||||
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||
import com.nimbusds.jose.proc.SecurityContext;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.security.oauth2.jose.TestJwks;
|
||||
import org.springframework.security.oauth2.jose.TestKeys;
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.willAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
/**
|
||||
* Tests for {@link NimbusJwsEncoder}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class NimbusJwsEncoderTests {
|
||||
|
||||
private List<JWK> jwkList;
|
||||
|
||||
private JWKSource<SecurityContext> jwkSource;
|
||||
|
||||
private NimbusJwsEncoder jwsEncoder;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.jwkList = new ArrayList<>();
|
||||
this.jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(new JWKSet(this.jwkList));
|
||||
this.jwsEncoder = new NimbusJwsEncoder(this.jwkSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenJwkSourceNullThenThrowIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new NimbusJwsEncoder(null))
|
||||
.withMessage("jwkSource cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWhenHeadersNullThenThrowIllegalArgumentException() {
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.jwsEncoder.encode(null, jwtClaimsSet))
|
||||
.withMessage("headers cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWhenClaimsNullThenThrowIllegalArgumentException() {
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader().build();
|
||||
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.jwsEncoder.encode(joseHeader, null))
|
||||
.withMessage("claims cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWhenJwkSelectFailedThenThrowJwtEncodingException() throws Exception {
|
||||
this.jwkSource = mock(JWKSource.class);
|
||||
this.jwsEncoder = new NimbusJwsEncoder(this.jwkSource);
|
||||
given(this.jwkSource.get(any(), any())).willThrow(new KeySourceException("key source error"));
|
||||
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader().build();
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
|
||||
assertThatExceptionOfType(JwtEncodingException.class)
|
||||
.isThrownBy(() -> this.jwsEncoder.encode(joseHeader, jwtClaimsSet))
|
||||
.withMessageContaining("Failed to select a JWK signing key -> key source error");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWhenJwkMultipleSelectedThenThrowJwtEncodingException() throws Exception {
|
||||
RSAKey rsaJwk = TestJwks.DEFAULT_RSA_JWK;
|
||||
this.jwkList.add(rsaJwk);
|
||||
this.jwkList.add(rsaJwk);
|
||||
|
||||
JoseHeader joseHeader = JoseHeader.withAlgorithm(SignatureAlgorithm.RS256).build();
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
|
||||
assertThatExceptionOfType(JwtEncodingException.class)
|
||||
.isThrownBy(() -> this.jwsEncoder.encode(joseHeader, jwtClaimsSet))
|
||||
.withMessageContaining("Found multiple JWK signing keys for algorithm 'RS256'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWhenJwkSelectEmptyThenThrowJwtEncodingException() {
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader().build();
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
|
||||
assertThatExceptionOfType(JwtEncodingException.class)
|
||||
.isThrownBy(() -> this.jwsEncoder.encode(joseHeader, jwtClaimsSet))
|
||||
.withMessageContaining("Failed to select a JWK signing key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWhenJwkUseEncryptionThenThrowJwtEncodingException() throws Exception {
|
||||
// @formatter:off
|
||||
RSAKey rsaJwk = TestJwks.jwk(TestKeys.DEFAULT_PUBLIC_KEY, TestKeys.DEFAULT_PRIVATE_KEY)
|
||||
.keyUse(KeyUse.ENCRYPTION)
|
||||
.build();
|
||||
// @formatter:on
|
||||
|
||||
this.jwkSource = mock(JWKSource.class);
|
||||
this.jwsEncoder = new NimbusJwsEncoder(this.jwkSource);
|
||||
given(this.jwkSource.get(any(), any())).willReturn(Collections.singletonList(rsaJwk));
|
||||
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader().build();
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
|
||||
assertThatExceptionOfType(JwtEncodingException.class)
|
||||
.isThrownBy(() -> this.jwsEncoder.encode(joseHeader, jwtClaimsSet)).withMessageContaining(
|
||||
"Failed to create a JWS Signer -> The JWK use must be sig (signature) or unspecified");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWhenSuccessThenDecodes() throws Exception {
|
||||
RSAKey rsaJwk = TestJwks.DEFAULT_RSA_JWK;
|
||||
this.jwkList.add(rsaJwk);
|
||||
|
||||
JoseHeader joseHeader = JoseHeader.withAlgorithm(SignatureAlgorithm.RS256).build();
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
|
||||
Jwt encodedJws = this.jwsEncoder.encode(joseHeader, jwtClaimsSet);
|
||||
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.ALG)).isEqualTo(joseHeader.getAlgorithm());
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.JKU)).isNull();
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.JWK)).isNull();
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.KID)).isEqualTo(rsaJwk.getKeyID());
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.X5U)).isNull();
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.X5C)).isNull();
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.X5T)).isNull();
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.X5T_S256)).isNull();
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.TYP)).isNull();
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.CTY)).isNull();
|
||||
assertThat(encodedJws.getHeaders().get(JoseHeaderNames.CRIT)).isNull();
|
||||
|
||||
assertThat(encodedJws.getIssuer()).isEqualTo(jwtClaimsSet.getIssuer());
|
||||
assertThat(encodedJws.getSubject()).isEqualTo(jwtClaimsSet.getSubject());
|
||||
assertThat(encodedJws.getAudience()).isEqualTo(jwtClaimsSet.getAudience());
|
||||
assertThat(encodedJws.getExpiresAt()).isEqualTo(jwtClaimsSet.getExpiresAt());
|
||||
assertThat(encodedJws.getNotBefore()).isEqualTo(jwtClaimsSet.getNotBefore());
|
||||
assertThat(encodedJws.getIssuedAt()).isEqualTo(jwtClaimsSet.getIssuedAt());
|
||||
assertThat(encodedJws.getId()).isEqualTo(jwtClaimsSet.getId());
|
||||
assertThat(encodedJws.<String>getClaim("custom-claim-name")).isEqualTo("custom-claim-value");
|
||||
|
||||
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey(rsaJwk.toRSAPublicKey()).build();
|
||||
jwtDecoder.decode(encodedJws.getTokenValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWhenKeysRotatedThenNewKeyUsed() throws Exception {
|
||||
TestJWKSource jwkSource = new TestJWKSource();
|
||||
JWKSource<SecurityContext> jwkSourceDelegate = spy(new JWKSource<SecurityContext>() {
|
||||
@Override
|
||||
public List<JWK> get(JWKSelector jwkSelector, SecurityContext context) {
|
||||
return jwkSource.get(jwkSelector, context);
|
||||
}
|
||||
});
|
||||
NimbusJwsEncoder jwsEncoder = new NimbusJwsEncoder(jwkSourceDelegate);
|
||||
|
||||
JwkListResultCaptor jwkListResultCaptor = new JwkListResultCaptor();
|
||||
willAnswer(jwkListResultCaptor).given(jwkSourceDelegate).get(any(), any());
|
||||
|
||||
JoseHeader joseHeader = JoseHeader.withAlgorithm(SignatureAlgorithm.RS256).build();
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet().build();
|
||||
|
||||
Jwt encodedJws = jwsEncoder.encode(joseHeader, jwtClaimsSet);
|
||||
|
||||
JWK jwk1 = jwkListResultCaptor.getResult().get(0);
|
||||
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey(((RSAKey) jwk1).toRSAPublicKey()).build();
|
||||
jwtDecoder.decode(encodedJws.getTokenValue());
|
||||
|
||||
jwkSource.rotate(); // Trigger key rotation
|
||||
|
||||
encodedJws = jwsEncoder.encode(joseHeader, jwtClaimsSet);
|
||||
|
||||
JWK jwk2 = jwkListResultCaptor.getResult().get(0);
|
||||
jwtDecoder = NimbusJwtDecoder.withPublicKey(((RSAKey) jwk2).toRSAPublicKey()).build();
|
||||
jwtDecoder.decode(encodedJws.getTokenValue());
|
||||
|
||||
assertThat(jwk1.getKeyID()).isNotEqualTo(jwk2.getKeyID());
|
||||
}
|
||||
|
||||
private static final class JwkListResultCaptor implements Answer<List<JWK>> {
|
||||
|
||||
private List<JWK> result;
|
||||
|
||||
private List<JWK> getResult() {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<JWK> answer(InvocationOnMock invocationOnMock) throws Throwable {
|
||||
this.result = (List<JWK>) invocationOnMock.callRealMethod();
|
||||
return this.result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class TestJWKSource implements JWKSource<SecurityContext> {
|
||||
|
||||
private int keyId = 1000;
|
||||
|
||||
private JWKSet jwkSet;
|
||||
|
||||
private TestJWKSource() {
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JWK> get(JWKSelector jwkSelector, SecurityContext context) {
|
||||
return jwkSelector.select(this.jwkSet);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// @formatter:off
|
||||
RSAKey rsaJwk = TestJwks.jwk(TestKeys.DEFAULT_PUBLIC_KEY, TestKeys.DEFAULT_PRIVATE_KEY)
|
||||
.keyID("rsa-jwk-" + this.keyId++)
|
||||
.build();
|
||||
ECKey ecJwk = TestJwks.jwk((ECPublicKey) TestKeys.DEFAULT_EC_KEY_PAIR.getPublic(), (ECPrivateKey) TestKeys.DEFAULT_EC_KEY_PAIR.getPrivate())
|
||||
.keyID("ec-jwk-" + this.keyId++)
|
||||
.build();
|
||||
OctetSequenceKey secretJwk = TestJwks.jwk(TestKeys.DEFAULT_SECRET_KEY)
|
||||
.keyID("secret-jwk-" + this.keyId++)
|
||||
.build();
|
||||
// @formatter:on
|
||||
this.jwkSet = new JWKSet(Arrays.asList(rsaJwk, ecJwk, secretJwk));
|
||||
}
|
||||
|
||||
private void rotate() {
|
||||
init();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2021 the original author or authors.
|
||||
* Copyright 2020-2022 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.
|
||||
@@ -24,18 +24,18 @@ import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
/**
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public final class TestJoseHeaders {
|
||||
public final class TestJwsHeaders {
|
||||
|
||||
private TestJoseHeaders() {
|
||||
private TestJwsHeaders() {
|
||||
}
|
||||
|
||||
public static JoseHeader.Builder joseHeader() {
|
||||
return joseHeader(SignatureAlgorithm.RS256);
|
||||
public static JwsHeader.Builder jwsHeader() {
|
||||
return jwsHeader(SignatureAlgorithm.RS256);
|
||||
}
|
||||
|
||||
public static JoseHeader.Builder joseHeader(SignatureAlgorithm signatureAlgorithm) {
|
||||
public static JwsHeader.Builder jwsHeader(SignatureAlgorithm signatureAlgorithm) {
|
||||
// @formatter:off
|
||||
return JoseHeader.withAlgorithm(signatureAlgorithm)
|
||||
return JwsHeader.with(signatureAlgorithm)
|
||||
.jwkSetUrl("https://provider.com/oauth2/jwks")
|
||||
.jwk(rsaJwk())
|
||||
.keyId("keyId")
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2021 the original author or authors.
|
||||
* Copyright 2020-2022 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.
|
||||
@@ -23,9 +23,9 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenType;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||
import org.springframework.security.oauth2.jwt.JoseHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwsHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||
import org.springframework.security.oauth2.jwt.TestJoseHeaders;
|
||||
import org.springframework.security.oauth2.jwt.TestJwsHeaders;
|
||||
import org.springframework.security.oauth2.jwt.TestJwtClaimsSets;
|
||||
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken;
|
||||
@@ -52,7 +52,7 @@ public class JwtEncodingContextTests {
|
||||
|
||||
@Test
|
||||
public void withWhenClaimsNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> JwtEncodingContext.with(TestJoseHeaders.joseHeader(), null))
|
||||
assertThatThrownBy(() -> JwtEncodingContext.with(TestJwsHeaders.jwsHeader(), null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("claimsBuilder cannot be null");
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class JwtEncodingContextTests {
|
||||
@Test
|
||||
public void setWhenValueNullThenThrowIllegalArgumentException() {
|
||||
JwtEncodingContext.Builder builder = JwtEncodingContext
|
||||
.with(TestJoseHeaders.joseHeader(), TestJwtClaimsSets.jwtClaimsSet());
|
||||
.with(TestJwsHeaders.jwsHeader(), TestJwtClaimsSets.jwtClaimsSet());
|
||||
assertThatThrownBy(() -> builder.registeredClient(null))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
assertThatThrownBy(() -> builder.principal(null))
|
||||
@@ -79,7 +79,7 @@ public class JwtEncodingContextTests {
|
||||
|
||||
@Test
|
||||
public void buildWhenAllValuesProvidedThenAllValuesAreSet() {
|
||||
JoseHeader.Builder headers = TestJoseHeaders.joseHeader();
|
||||
JwsHeader.Builder headers = TestJwsHeaders.jwsHeader();
|
||||
JwtClaimsSet.Builder claims = TestJwtClaimsSets.jwtClaimsSet();
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
|
||||
TestingAuthenticationToken principal = new TestingAuthenticationToken("principal", "password");
|
||||
|
||||
@@ -44,12 +44,13 @@ import org.springframework.security.oauth2.jose.TestKeys;
|
||||
import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.BadJwtException;
|
||||
import org.springframework.security.oauth2.jwt.JoseHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwsHeader;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
|
||||
import org.springframework.security.oauth2.jwt.JwtValidationException;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwsEncoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
|
||||
@@ -303,7 +304,7 @@ public class JwtClientAssertionAuthenticationProviderTests {
|
||||
.thenReturn(registeredClient);
|
||||
|
||||
// @formatter:off
|
||||
JoseHeader joseHeader = JoseHeader.withAlgorithm(MacAlgorithm.HS256)
|
||||
JwsHeader jwsHeader = JwsHeader.with(MacAlgorithm.HS256)
|
||||
.build();
|
||||
JwtClaimsSet jwtClaimsSet = JwtClaimsSet.builder()
|
||||
.issuer("invalid-iss")
|
||||
@@ -313,7 +314,7 @@ public class JwtClientAssertionAuthenticationProviderTests {
|
||||
// @formatter:on
|
||||
|
||||
JwtEncoder jwsEncoder = createEncoder(TestKeys.DEFAULT_ENCODED_SECRET_KEY, "HmacSHA256");
|
||||
Jwt jwtAssertion = jwsEncoder.encode(joseHeader, jwtClaimsSet);
|
||||
Jwt jwtAssertion = jwsEncoder.encode(JwtEncoderParameters.from(jwsHeader, jwtClaimsSet));
|
||||
|
||||
OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken(
|
||||
registeredClient.getClientId(), JWT_CLIENT_ASSERTION_AUTHENTICATION_METHOD, jwtAssertion.getTokenValue(), null);
|
||||
@@ -346,14 +347,14 @@ public class JwtClientAssertionAuthenticationProviderTests {
|
||||
.thenReturn(registeredClient);
|
||||
|
||||
// @formatter:off
|
||||
JoseHeader joseHeader = JoseHeader.withAlgorithm(MacAlgorithm.HS256)
|
||||
JwsHeader jwsHeader = JwsHeader.with(MacAlgorithm.HS256)
|
||||
.build();
|
||||
JwtClaimsSet jwtClaimsSet = jwtClientAssertionClaims(registeredClient)
|
||||
.build();
|
||||
// @formatter:on
|
||||
|
||||
JwtEncoder jwsEncoder = createEncoder(TestKeys.DEFAULT_ENCODED_SECRET_KEY, "HmacSHA256");
|
||||
Jwt jwtAssertion = jwsEncoder.encode(joseHeader, jwtClaimsSet);
|
||||
Jwt jwtAssertion = jwsEncoder.encode(JwtEncoderParameters.from(jwsHeader, jwtClaimsSet));
|
||||
|
||||
OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken(
|
||||
registeredClient.getClientId(), JWT_CLIENT_ASSERTION_AUTHENTICATION_METHOD, jwtAssertion.getTokenValue(), null);
|
||||
@@ -392,14 +393,14 @@ public class JwtClientAssertionAuthenticationProviderTests {
|
||||
Map<String, Object> parameters = createPkceTokenParameters(S256_CODE_VERIFIER);
|
||||
|
||||
// @formatter:off
|
||||
JoseHeader joseHeader = JoseHeader.withAlgorithm(MacAlgorithm.HS256)
|
||||
JwsHeader jwsHeader = JwsHeader.with(MacAlgorithm.HS256)
|
||||
.build();
|
||||
JwtClaimsSet jwtClaimsSet = jwtClientAssertionClaims(registeredClient)
|
||||
.build();
|
||||
// @formatter:on
|
||||
|
||||
JwtEncoder jwsEncoder = createEncoder(TestKeys.DEFAULT_ENCODED_SECRET_KEY, "HmacSHA256");
|
||||
Jwt jwtAssertion = jwsEncoder.encode(joseHeader, jwtClaimsSet);
|
||||
Jwt jwtAssertion = jwsEncoder.encode(JwtEncoderParameters.from(jwsHeader, jwtClaimsSet));
|
||||
|
||||
OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken(
|
||||
registeredClient.getClientId(), JWT_CLIENT_ASSERTION_AUTHENTICATION_METHOD, jwtAssertion.getTokenValue(), parameters);
|
||||
@@ -430,7 +431,7 @@ public class JwtClientAssertionAuthenticationProviderTests {
|
||||
OctetSequenceKey secretKeyJwk = TestJwks.jwk(secretKey).build();
|
||||
JWKSource<SecurityContext> jwkSource = (jwkSelector, securityContext) ->
|
||||
jwkSelector.select(new JWKSet(secretKeyJwk));
|
||||
return new NimbusJwsEncoder(jwkSource);
|
||||
return new NimbusJwtEncoder(jwkSource);
|
||||
}
|
||||
|
||||
private static String asUrl(String uri, String path) {
|
||||
|
||||
@@ -50,17 +50,12 @@ import org.springframework.security.oauth2.jwt.JoseHeaderNames;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
|
||||
import org.springframework.security.oauth2.server.authorization.JwtEncodingContext;
|
||||
import org.springframework.security.oauth2.server.authorization.token.JwtGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2AccessTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2TokenContext;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
@@ -68,6 +63,12 @@ import org.springframework.security.oauth2.server.authorization.config.ProviderS
|
||||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.context.ProviderContext;
|
||||
import org.springframework.security.oauth2.server.authorization.context.ProviderContextHolder;
|
||||
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.JwtGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2AccessTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -351,7 +352,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
OAuth2AuthorizationCodeAuthenticationToken authentication =
|
||||
new OAuth2AuthorizationCodeAuthenticationToken(AUTHORIZATION_CODE, clientPrincipal, authorizationRequest.getRedirectUri(), null);
|
||||
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt());
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt());
|
||||
|
||||
doAnswer(answer -> {
|
||||
OAuth2TokenContext context = answer.getArgument(0);
|
||||
@@ -385,7 +386,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
OAuth2AuthorizationCodeAuthenticationToken authentication =
|
||||
new OAuth2AuthorizationCodeAuthenticationToken(AUTHORIZATION_CODE, clientPrincipal, authorizationRequest.getRedirectUri(), null);
|
||||
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt());
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt());
|
||||
|
||||
doAnswer(answer -> {
|
||||
OAuth2TokenContext context = answer.getArgument(0);
|
||||
@@ -419,7 +420,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
OAuth2AuthorizationCodeAuthenticationToken authentication =
|
||||
new OAuth2AuthorizationCodeAuthenticationToken(AUTHORIZATION_CODE, clientPrincipal, authorizationRequest.getRedirectUri(), null);
|
||||
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt());
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt());
|
||||
|
||||
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
||||
(OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
||||
@@ -438,9 +439,9 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
assertThat(jwtEncodingContext.getHeaders()).isNotNull();
|
||||
assertThat(jwtEncodingContext.getClaims()).isNotNull();
|
||||
|
||||
ArgumentCaptor<JwtClaimsSet> jwtClaimsSetCaptor = ArgumentCaptor.forClass(JwtClaimsSet.class);
|
||||
verify(this.jwtEncoder).encode(any(), jwtClaimsSetCaptor.capture());
|
||||
JwtClaimsSet jwtClaimsSet = jwtClaimsSetCaptor.getValue();
|
||||
ArgumentCaptor<JwtEncoderParameters> jwtEncoderParametersCaptor = ArgumentCaptor.forClass(JwtEncoderParameters.class);
|
||||
verify(this.jwtEncoder).encode(jwtEncoderParametersCaptor.capture());
|
||||
JwtClaimsSet jwtClaimsSet = jwtEncoderParametersCaptor.getValue().getClaims();
|
||||
|
||||
Set<String> scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE);
|
||||
assertThat(scopes).isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
|
||||
@@ -475,7 +476,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
OAuth2AuthorizationCodeAuthenticationToken authentication =
|
||||
new OAuth2AuthorizationCodeAuthenticationToken(AUTHORIZATION_CODE, clientPrincipal, authorizationRequest.getRedirectUri(), null);
|
||||
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt());
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt());
|
||||
|
||||
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
||||
(OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
||||
@@ -511,7 +512,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
assertThat(idTokenContext.getHeaders()).isNotNull();
|
||||
assertThat(idTokenContext.getClaims()).isNotNull();
|
||||
|
||||
verify(this.jwtEncoder, times(2)).encode(any(), any()); // Access token and ID Token
|
||||
verify(this.jwtEncoder, times(2)).encode(any()); // Access token and ID Token
|
||||
|
||||
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
|
||||
verify(this.authorizationService).save(authorizationCaptor.capture());
|
||||
@@ -549,7 +550,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
OAuth2AuthorizationCodeAuthenticationToken authentication =
|
||||
new OAuth2AuthorizationCodeAuthenticationToken(AUTHORIZATION_CODE, clientPrincipal, authorizationRequest.getRedirectUri(), null);
|
||||
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt());
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt());
|
||||
|
||||
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
||||
(OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
||||
@@ -568,9 +569,9 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
assertThat(jwtEncodingContext.getHeaders()).isNotNull();
|
||||
assertThat(jwtEncodingContext.getClaims()).isNotNull();
|
||||
|
||||
ArgumentCaptor<JwtClaimsSet> jwtClaimsSetCaptor = ArgumentCaptor.forClass(JwtClaimsSet.class);
|
||||
verify(this.jwtEncoder).encode(any(), jwtClaimsSetCaptor.capture());
|
||||
JwtClaimsSet jwtClaimsSet = jwtClaimsSetCaptor.getValue();
|
||||
ArgumentCaptor<JwtEncoderParameters> jwtEncoderParametersCaptor = ArgumentCaptor.forClass(JwtEncoderParameters.class);
|
||||
verify(this.jwtEncoder).encode(jwtEncoderParametersCaptor.capture());
|
||||
JwtClaimsSet jwtClaimsSet = jwtEncoderParametersCaptor.getValue().getClaims();
|
||||
|
||||
Set<String> scopes = jwtClaimsSet.getClaim(OAuth2ParameterNames.SCOPE);
|
||||
assertThat(scopes).isEqualTo(authorization.getAttribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME));
|
||||
@@ -614,7 +615,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
|
||||
Instant accessTokenIssuedAt = Instant.now();
|
||||
Instant accessTokenExpiresAt = accessTokenIssuedAt.plus(accessTokenTTL);
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt(accessTokenIssuedAt, accessTokenExpiresAt));
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt(accessTokenIssuedAt, accessTokenExpiresAt));
|
||||
|
||||
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
||||
(OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
||||
@@ -651,7 +652,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
OAuth2AuthorizationCodeAuthenticationToken authentication =
|
||||
new OAuth2AuthorizationCodeAuthenticationToken(AUTHORIZATION_CODE, clientPrincipal, authorizationRequest.getRedirectUri(), null);
|
||||
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt());
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt());
|
||||
|
||||
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
||||
(OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
||||
@@ -666,7 +667,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
when(this.authorizationService.findByToken(eq(AUTHORIZATION_CODE), eq(AUTHORIZATION_CODE_TOKEN_TYPE)))
|
||||
.thenReturn(authorization);
|
||||
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt());
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Supplier<String> refreshTokenGenerator = spy(new Supplier<String>() {
|
||||
|
||||
@@ -39,22 +39,22 @@ import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.JoseHeaderNames;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.JwtEncodingContext;
|
||||
import org.springframework.security.oauth2.server.authorization.token.JwtGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2AccessTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2TokenContext;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.context.ProviderContext;
|
||||
import org.springframework.security.oauth2.server.authorization.context.ProviderContextHolder;
|
||||
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.JwtGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2AccessTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -217,7 +217,7 @@ public class OAuth2ClientCredentialsAuthenticationProviderTests {
|
||||
OAuth2ClientCredentialsAuthenticationToken authentication =
|
||||
new OAuth2ClientCredentialsAuthenticationToken(clientPrincipal, requestedScope, null);
|
||||
|
||||
when(this.jwtEncoder.encode(any(), any()))
|
||||
when(this.jwtEncoder.encode(any()))
|
||||
.thenReturn(createJwt(Collections.singleton("mapped-scoped")));
|
||||
|
||||
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
||||
@@ -252,7 +252,7 @@ public class OAuth2ClientCredentialsAuthenticationProviderTests {
|
||||
OAuth2ClientCredentialsAuthenticationToken authentication =
|
||||
new OAuth2ClientCredentialsAuthenticationToken(clientPrincipal, null, null);
|
||||
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt(registeredClient.getScopes()));
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt(registeredClient.getScopes()));
|
||||
|
||||
OAuth2AccessTokenAuthenticationToken accessTokenAuthentication =
|
||||
(OAuth2AccessTokenAuthenticationToken) this.authenticationProvider.authenticate(authentication);
|
||||
|
||||
@@ -48,17 +48,11 @@ import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.JoseHeaderNames;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.JwtEncodingContext;
|
||||
import org.springframework.security.oauth2.server.authorization.token.JwtGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2AccessTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2TokenContext;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
@@ -66,6 +60,12 @@ import org.springframework.security.oauth2.server.authorization.config.ProviderS
|
||||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.context.ProviderContext;
|
||||
import org.springframework.security.oauth2.server.authorization.context.ProviderContextHolder;
|
||||
import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.JwtGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2AccessTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext;
|
||||
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -99,7 +99,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
|
||||
public void setUp() {
|
||||
this.authorizationService = mock(OAuth2AuthorizationService.class);
|
||||
this.jwtEncoder = mock(JwtEncoder.class);
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwt(Collections.singleton("scope1")));
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwt(Collections.singleton("scope1")));
|
||||
this.jwtCustomizer = mock(OAuth2TokenCustomizer.class);
|
||||
JwtGenerator jwtGenerator = new JwtGenerator(this.jwtEncoder);
|
||||
jwtGenerator.setJwtCustomizer(this.jwtCustomizer);
|
||||
@@ -265,7 +265,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
|
||||
assertThat(idTokenContext.getHeaders()).isNotNull();
|
||||
assertThat(idTokenContext.getClaims()).isNotNull();
|
||||
|
||||
verify(this.jwtEncoder, times(2)).encode(any(), any()); // Access token and ID Token
|
||||
verify(this.jwtEncoder, times(2)).encode(any()); // Access token and ID Token
|
||||
|
||||
ArgumentCaptor<OAuth2Authorization> authorizationCaptor = ArgumentCaptor.forClass(OAuth2Authorization.class);
|
||||
verify(this.authorizationService).save(authorizationCaptor.capture());
|
||||
|
||||
@@ -42,11 +42,11 @@ import org.springframework.security.oauth2.core.oidc.OidcClientMetadataClaimName
|
||||
import org.springframework.security.oauth2.core.oidc.OidcClientRegistration;
|
||||
import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.JoseHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwsHeader;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.jwt.TestJoseHeaders;
|
||||
import org.springframework.security.oauth2.jwt.TestJwsHeaders;
|
||||
import org.springframework.security.oauth2.jwt.TestJwtClaimsSets;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
@@ -451,7 +451,7 @@ public class OidcClientRegistrationAuthenticationProviderTests {
|
||||
when(this.authorizationService.findByToken(
|
||||
eq(jwtAccessToken.getTokenValue()), eq(OAuth2TokenType.ACCESS_TOKEN)))
|
||||
.thenReturn(authorization);
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwtClientConfiguration());
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwtClientConfiguration());
|
||||
|
||||
JwtAuthenticationToken principal = new JwtAuthenticationToken(
|
||||
jwt, AuthorityUtils.createAuthorityList("SCOPE_client.create"));
|
||||
@@ -538,7 +538,7 @@ public class OidcClientRegistrationAuthenticationProviderTests {
|
||||
when(this.authorizationService.findByToken(
|
||||
eq(jwtAccessToken.getTokenValue()), eq(OAuth2TokenType.ACCESS_TOKEN)))
|
||||
.thenReturn(authorization);
|
||||
when(this.jwtEncoder.encode(any(), any())).thenReturn(createJwtClientConfiguration());
|
||||
when(this.jwtEncoder.encode(any())).thenReturn(createJwtClientConfiguration());
|
||||
|
||||
JwtAuthenticationToken principal = new JwtAuthenticationToken(
|
||||
jwt, AuthorityUtils.createAuthorityList("SCOPE_client.create"));
|
||||
@@ -565,7 +565,7 @@ public class OidcClientRegistrationAuthenticationProviderTests {
|
||||
eq(jwtAccessToken.getTokenValue()), eq(OAuth2TokenType.ACCESS_TOKEN));
|
||||
verify(this.registeredClientRepository).save(registeredClientCaptor.capture());
|
||||
verify(this.authorizationService, times(2)).save(authorizationCaptor.capture());
|
||||
verify(this.jwtEncoder).encode(any(), any());
|
||||
verify(this.jwtEncoder).encode(any());
|
||||
|
||||
// assert "registration" access token, which should be used for subsequent calls to client configuration endpoint
|
||||
OAuth2Authorization authorizationResult = authorizationCaptor.getAllValues().get(0);
|
||||
@@ -834,13 +834,13 @@ public class OidcClientRegistrationAuthenticationProviderTests {
|
||||
|
||||
private static Jwt createJwt(Set<String> scopes) {
|
||||
// @formatter:off
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader()
|
||||
JwsHeader jwsHeader = TestJwsHeaders.jwsHeader()
|
||||
.build();
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet()
|
||||
.claim(OAuth2ParameterNames.SCOPE, scopes)
|
||||
.build();
|
||||
Jwt jwt = Jwt.withTokenValue("jwt-access-token")
|
||||
.headers(headers -> headers.putAll(joseHeader.getHeaders()))
|
||||
.headers(headers -> headers.putAll(jwsHeader.getHeaders()))
|
||||
.claims(claims -> claims.putAll(jwtClaimsSet.getClaims()))
|
||||
.build();
|
||||
// @formatter:on
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2021 the original author or authors.
|
||||
* Copyright 2020-2022 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.
|
||||
@@ -47,10 +47,10 @@ import org.springframework.security.oauth2.core.http.converter.OAuth2ErrorHttpMe
|
||||
import org.springframework.security.oauth2.core.oidc.OidcClientRegistration;
|
||||
import org.springframework.security.oauth2.core.oidc.http.converter.OidcClientRegistrationHttpMessageConverter;
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.JoseHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwsHeader;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||
import org.springframework.security.oauth2.jwt.TestJoseHeaders;
|
||||
import org.springframework.security.oauth2.jwt.TestJwsHeaders;
|
||||
import org.springframework.security.oauth2.jwt.TestJwtClaimsSets;
|
||||
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||
@@ -473,13 +473,13 @@ public class OidcClientRegistrationEndpointFilterTests {
|
||||
|
||||
private static Jwt createJwt(String scope) {
|
||||
// @formatter:off
|
||||
JoseHeader joseHeader = TestJoseHeaders.joseHeader()
|
||||
JwsHeader jwsHeader = TestJwsHeaders.jwsHeader()
|
||||
.build();
|
||||
JwtClaimsSet jwtClaimsSet = TestJwtClaimsSets.jwtClaimsSet()
|
||||
.claim(OAuth2ParameterNames.SCOPE, Collections.singleton(scope))
|
||||
.build();
|
||||
Jwt jwt = Jwt.withTokenValue("jwt-access-token")
|
||||
.headers(headers -> headers.putAll(joseHeader.getHeaders()))
|
||||
.headers(headers -> headers.putAll(jwsHeader.getHeaders()))
|
||||
.claims(claims -> claims.putAll(jwtClaimsSet.getClaims()))
|
||||
.build();
|
||||
// @formatter:on
|
||||
|
||||
@@ -36,11 +36,11 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcScopes;
|
||||
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
|
||||
import org.springframework.security.oauth2.jose.jws.JwsAlgorithm;
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.JoseHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwsHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
|
||||
import org.springframework.security.oauth2.server.authorization.JwtEncodingContext;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2TokenContext;
|
||||
@@ -200,14 +200,13 @@ public class JwtGeneratorTests {
|
||||
assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(tokenContext.getAuthorizationGrantType());
|
||||
assertThat(jwtEncodingContext.<Authentication>getAuthorizationGrant()).isEqualTo(tokenContext.getAuthorizationGrant());
|
||||
|
||||
ArgumentCaptor<JoseHeader> joseHeaderCaptor = ArgumentCaptor.forClass(JoseHeader.class);
|
||||
ArgumentCaptor<JwtClaimsSet> jwtClaimsSetCaptor = ArgumentCaptor.forClass(JwtClaimsSet.class);
|
||||
verify(this.jwtEncoder).encode(joseHeaderCaptor.capture(), jwtClaimsSetCaptor.capture());
|
||||
ArgumentCaptor<JwtEncoderParameters> jwtEncoderParametersCaptor = ArgumentCaptor.forClass(JwtEncoderParameters.class);
|
||||
verify(this.jwtEncoder).encode(jwtEncoderParametersCaptor.capture());
|
||||
|
||||
JoseHeader joseHeader = joseHeaderCaptor.getValue();
|
||||
assertThat(joseHeader.<JwsAlgorithm>getAlgorithm()).isEqualTo(SignatureAlgorithm.RS256);
|
||||
JwsHeader jwsHeader = jwtEncoderParametersCaptor.getValue().getJwsHeader();
|
||||
assertThat(jwsHeader.getAlgorithm()).isEqualTo(SignatureAlgorithm.RS256);
|
||||
|
||||
JwtClaimsSet jwtClaimsSet = jwtClaimsSetCaptor.getValue();
|
||||
JwtClaimsSet jwtClaimsSet = jwtEncoderParametersCaptor.getValue().getClaims();
|
||||
assertThat(jwtClaimsSet.getIssuer().toExternalForm()).isEqualTo(tokenContext.getProviderContext().getIssuer());
|
||||
assertThat(jwtClaimsSet.getSubject()).isEqualTo(tokenContext.getAuthorization().getPrincipalName());
|
||||
assertThat(jwtClaimsSet.getAudience()).containsExactly(tokenContext.getRegisteredClient().getClientId());
|
||||
|
||||
Reference in New Issue
Block a user