diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java index 0d7ca20a..5699e0e6 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java @@ -463,6 +463,7 @@ private ActivationLayer1Response processOidcActivation(final EncryptionContext e .providerId(identity.get("providerId")) .code(identity.get("code")) .nonce(identity.get("nonce")) + .codeVerifier(identity.get("codeVerifier")) .applicationKey(eciesContext.getApplicationKey()) .build(); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcActivationContext.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcActivationContext.java index c4e10a64..9601c93f 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcActivationContext.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcActivationContext.java @@ -33,6 +33,7 @@ public class OidcActivationContext { private String code; private String nonce; + private String codeVerifier; private String applicationKey; private String providerId; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcApplicationConfiguration.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcApplicationConfiguration.java index c78b20c1..93e83c34 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcApplicationConfiguration.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcApplicationConfiguration.java @@ -59,4 +59,9 @@ public class OidcApplicationConfiguration { */ private String signatureAlgorithm; + /** + * A hint for the mobile application whether to user PKCE. + */ + private boolean pkceEnabled; + } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcHandler.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcHandler.java index 399590d7..9a076d14 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcHandler.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcHandler.java @@ -80,6 +80,7 @@ public String retrieveUserId(final OidcActivationContext request) throws PowerAu final TokenRequest tokenRequest = TokenRequest.builder() .code(request.getCode()) + .codeVerifier(request.getCodeVerifier()) .clientRegistration(clientRegistration) .build(); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcTokenClient.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcTokenClient.java index 9a7fdb61..b784803c 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcTokenClient.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcTokenClient.java @@ -25,6 +25,7 @@ import com.wultra.core.rest.client.base.RestClientException; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -68,6 +69,11 @@ TokenResponse fetchTokenResponse(final TokenRequest tokenRequest) throws RestCli map.add("code", tokenRequest.getCode()); map.add("redirect_uri", clientRegistration.getRedirectUri()); + final String codeVerifier = tokenRequest.getCodeVerifier(); + if (StringUtils.isNoneBlank(codeVerifier)) { + map.add("code_verifier", codeVerifier); + } + if (clientAuthenticationMethod == org.springframework.security.oauth2.core.ClientAuthenticationMethod.CLIENT_SECRET_POST) { map.add("client_secret", clientRegistration.getClientSecret()); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/TokenRequest.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/TokenRequest.java index b5f6372c..7a4171f3 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/TokenRequest.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/TokenRequest.java @@ -35,4 +35,9 @@ class TokenRequest { private String code; private ClientRegistration clientRegistration; + /** + * Optional. Required only for PKCE. + */ + private String codeVerifier; + } diff --git a/powerauth-restful-security-spring/src/test/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcApplicationConfigurationServiceTest.java b/powerauth-restful-security-spring/src/test/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcApplicationConfigurationServiceTest.java index 9b36cd50..1ea156f0 100644 --- a/powerauth-restful-security-spring/src/test/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcApplicationConfigurationServiceTest.java +++ b/powerauth-restful-security-spring/src/test/java/io/getlime/security/powerauth/rest/api/spring/service/oidc/OidcApplicationConfigurationServiceTest.java @@ -33,8 +33,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.when; /** @@ -84,6 +83,7 @@ void testFetchOidcApplicationConfiguration() throws Exception { assertEquals("https://token.example.com", result.getTokenUri()); assertEquals("https://authorize.example.com", result.getAuthorizeUri()); assertEquals("ES256", result.getSignatureAlgorithm()); + assertFalse(result.isPkceEnabled()); } @Test