This is an automated email from the ASF dual-hosted git repository.
pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 547f338147 NIFI-12695 Enabled PKCE Support for OIDC Integration
547f338147 is described below
commit 547f338147f4c48d9612ce4e7a6d52e0d8714f7f
Author: exceptionfactory <[email protected]>
AuthorDate: Tue Jan 30 21:59:42 2024 -0600
NIFI-12695 Enabled PKCE Support for OIDC Integration
- Added Spring Security PKCE OAuth2 Request Customizer to standard Resolver
Signed-off-by: Pierre Villard <[email protected]>
This closes #8324.
---
nifi-docs/src/main/asciidoc/administration-guide.adoc | 3 +++
.../web/StandardOAuth2AuthorizationRequestResolver.java | 9 +++++++--
.../StandardOAuth2AuthorizationRequestResolverTest.java | 14 ++++++++++++++
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc
b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index 66ac8ef0f2..97ef2e8728 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -518,6 +518,9 @@ The implementation supports the Authorization Code Grant
Type as described in
link:https://www.rfc-editor.org/rfc/rfc6749#section-4.1[RFC 6749 Section 4.1^]
and
link:https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowSteps[OpenID
Connect Core Section 3.1.1^].
+The Authorization Code Grant Type implementation supports
link:https://www.rfc-editor.org/rfc/rfc7636[RFC 7636] Proof
+Key for Code Exchange as part of the authentication process. PKCE support uses
the `S256` code challenge method.
+
After successful authentication with the Authorization Server, NiFi generates
an application Bearer Token with an
expiration based on the OAuth2 Access Token expiration. NiFi stores authorized
tokens using the local State
Provider and encrypts serialized information using the application Sensitive
Properties Key.
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolver.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolver.java
index 17bfee9878..39c397e20d 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolver.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolver.java
@@ -19,7 +19,7 @@ package org.apache.nifi.web.security.oidc.client.web;
import org.apache.nifi.web.util.RequestUriBuilder;
import
org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import
org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver;
-import
org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
+import
org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestCustomizers;
import
org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
import
org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.web.util.UriComponentsBuilder;
@@ -28,6 +28,8 @@ import jakarta.servlet.http.HttpServletRequest;
import java.net.URI;
import java.util.Objects;
+import static
org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI;
+
/**
* Authorization Request Resolver supports handling of headers from reverse
proxy servers
*/
@@ -41,7 +43,10 @@ public class StandardOAuth2AuthorizationRequestResolver
implements OAuth2Authori
*/
public StandardOAuth2AuthorizationRequestResolver(final
ClientRegistrationRepository clientRegistrationRepository) {
Objects.requireNonNull(clientRegistrationRepository, "Repository
required");
- resolver = new
DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository,
OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI);
+ final DefaultOAuth2AuthorizationRequestResolver requestResolver = new
DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository,
DEFAULT_AUTHORIZATION_REQUEST_BASE_URI);
+ // Enable RFC 7636 Proof Key for Code Exchange on Requests
+
requestResolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce());
+ resolver = requestResolver;
}
/**
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolverTest.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolverTest.java
index a06ba3accc..6b36272318 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolverTest.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolverTest.java
@@ -30,11 +30,15 @@ import
org.springframework.security.oauth2.core.AuthorizationGrantType;
import
org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import jakarta.servlet.ServletContext;
+import org.springframework.security.oauth2.core.endpoint.PkceParameterNames;
+
import java.net.URI;
+import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@@ -99,6 +103,7 @@ class StandardOAuth2AuthorizationRequestResolverTest {
assertNotNull(authorizationRequest);
assertEquals(REDIRECT_URI, authorizationRequest.getRedirectUri());
+ assertPkceParametersFound(authorizationRequest);
}
@Test
@@ -119,6 +124,15 @@ class StandardOAuth2AuthorizationRequestResolverTest {
assertNotNull(authorizationRequest);
assertEquals(FORWARDED_REDIRECT_URI,
authorizationRequest.getRedirectUri());
+ assertPkceParametersFound(authorizationRequest);
+ }
+
+ private void assertPkceParametersFound(final OAuth2AuthorizationRequest
authorizationRequest) {
+
assertNotNull(authorizationRequest.getAttribute(PkceParameterNames.CODE_VERIFIER));
+
+ final Map<String, Object> additionalParameters =
authorizationRequest.getAdditionalParameters();
+
assertTrue(additionalParameters.containsKey(PkceParameterNames.CODE_CHALLENGE));
+
assertTrue(additionalParameters.containsKey(PkceParameterNames.CODE_CHALLENGE_METHOD));
}
ClientRegistration getClientRegistration() {