This is an automated email from the ASF dual-hosted git repository.
jfrazee 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 f330078 NIFI-7924 Add fallback claims for identifying user to OIDC
provider
f330078 is described below
commit f330078fffd39feeb2b289f7e9de5113f9c78bb4
Author: sjyang18 <[email protected]>
AuthorDate: Tue Oct 13 02:49:26 2020 +0000
NIFI-7924 Add fallback claims for identifying user to OIDC provider
This closes #4630
Signed-off-by: Joey Frazee <[email protected]>
---
.../java/org/apache/nifi/util/NiFiProperties.java | 16 ++++++++++++++++
.../src/main/asciidoc/administration-guide.adoc | 1 +
.../nifi-framework/nifi-resources/pom.xml | 1 +
.../src/main/resources/conf/nifi.properties | 1 +
.../security/oidc/StandardOidcIdentityProvider.java | 12 ++++++++++--
.../StandardOidcIdentityProviderGroovyTest.groovy | 20 +++++++++++++++++++-
6 files changed, 48 insertions(+), 3 deletions(-)
diff --git
a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
index 6164a2e..af48f02 100644
---
a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
+++
b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
@@ -169,6 +169,7 @@ public abstract class NiFiProperties {
public static final String SECURITY_USER_OIDC_PREFERRED_JWSALGORITHM =
"nifi.security.user.oidc.preferred.jwsalgorithm";
public static final String SECURITY_USER_OIDC_ADDITIONAL_SCOPES =
"nifi.security.user.oidc.additional.scopes";
public static final String SECURITY_USER_OIDC_CLAIM_IDENTIFYING_USER =
"nifi.security.user.oidc.claim.identifying.user";
+ public static final String
SECURITY_USER_OIDC_FALLBACK_CLAIMS_IDENTIFYING_USER =
"nifi.security.user.oidc.fallback.claims.identifying.user";
// apache knox
public static final String SECURITY_USER_KNOX_URL =
"nifi.security.user.knox.url";
@@ -1011,6 +1012,21 @@ public abstract class NiFiProperties {
return getProperty(SECURITY_USER_OIDC_CLAIM_IDENTIFYING_USER,
"email").trim();
}
+ /**
+ * Returns the list of fallback claims to be used to identify a user when
the configured claim is empty for a user
+ *
+ * @return The list of fallback claims to be used to identify the user
+ */
+ public List<String> getOidcFallbackClaimsIdentifyingUser() {
+ String rawProperty =
getProperty(SECURITY_USER_OIDC_FALLBACK_CLAIMS_IDENTIFYING_USER, "").trim();
+ if (StringUtils.isBlank(rawProperty)) {
+ return Collections.emptyList();
+ } else {
+ List<String> fallbackClaims =
Arrays.asList(rawProperty.split(","));
+ return
fallbackClaims.stream().map(String::trim).filter(s->!s.isEmpty()).collect(Collectors.toList());
+ }
+ }
+
public boolean shouldSendServerVersion() {
return
Boolean.parseBoolean(getProperty(WEB_SHOULD_SEND_SERVER_VERSION,
DEFAULT_WEB_SHOULD_SEND_SERVER_VERSION));
}
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc
b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index 08da126..d1856c9 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -373,6 +373,7 @@ If this value is `none`, NiFi will attempt to validate
unsecured/plain tokens. O
JSON Web Key (JWK) provided through the jwks_uri in the metadata found at the
discovery URL.
|`nifi.security.user.oidc.additional.scopes` | Comma separated scopes that are
sent to OpenId Connect Provider in addition to `openid` and `email`.
|`nifi.security.user.oidc.claim.identifying.user` | Claim that identifies the
user to be logged in; default is `email`. May need to be requested via the
`nifi.security.user.oidc.additional.scopes` before usage.
+|`nifi.security.user.oidc.fallback.claims.identifying.user` | Comma separated
possible fallback claims used to identify the user in case
`nifi.security.user.oidc.claim.identifying.user` claim is not present for the
login user.
|==================================================================================================================================================
[[saml]]
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
index 2013d87..6b6faec 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/pom.xml
@@ -164,6 +164,7 @@
<nifi.security.user.oidc.preferred.jwsalgorithm />
<nifi.security.user.oidc.additional.scopes />
<nifi.security.user.oidc.claim.identifying.user />
+ <nifi.security.user.oidc.fallback.claims.identifying.user />
<!-- nifi.properties: apache knox -->
<nifi.security.user.knox.url />
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
index be45e4a..a84bff9 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/nifi.properties
@@ -178,6 +178,7 @@
nifi.security.user.oidc.client.secret=${nifi.security.user.oidc.client.secret}
nifi.security.user.oidc.preferred.jwsalgorithm=${nifi.security.user.oidc.preferred.jwsalgorithm}
nifi.security.user.oidc.additional.scopes=${nifi.security.user.oidc.additional.scopes}
nifi.security.user.oidc.claim.identifying.user=${nifi.security.user.oidc.claim.identifying.user}
+nifi.security.user.oidc.fallback.claims.identifying.user=${nifi.security.user.oidc.fallback.claims.identifying.user}
# Apache Knox SSO Properties #
nifi.security.user.knox.url=${nifi.security.user.knox.url}
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/StandardOidcIdentityProvider.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/StandardOidcIdentityProvider.java
index a26926e..b69679c 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/StandardOidcIdentityProvider.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/StandardOidcIdentityProvider.java
@@ -439,8 +439,16 @@ public class StandardOidcIdentityProvider implements
OidcIdentityProvider {
identity = claimsSet.getStringClaim(EMAIL_CLAIM);
logger.info("The 'email' claim was present. Using that claim
to avoid extra remote call");
} else {
- identity = retrieveIdentityFromUserInfoEndpoint(oidcTokens);
- logger.info("Retrieved identity from UserInfo endpoint");
+ final List<String> fallbackClaims =
properties.getOidcFallbackClaimsIdentifyingUser();
+ for (String fallbackClaim : fallbackClaims) {
+ if (availableClaims.contains(fallbackClaim)) {
+ identity = claimsSet.getStringClaim(fallbackClaim);
+ break;
+ }
+ }
+ if (StringUtils.isBlank(identity)) {
+ identity =
retrieveIdentityFromUserInfoEndpoint(oidcTokens);
+ }
}
}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/groovy/org/apache/nifi/web/security/oidc/StandardOidcIdentityProviderGroovyTest.groovy
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/groovy/org/apache/nifi/web/security/oidc/StandardOidcIdentityProviderGroovyTest.groovy
index b42881a..c52d4cd 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/groovy/org/apache/nifi/web/security/oidc/StandardOidcIdentityProviderGroovyTest.groovy
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/groovy/org/apache/nifi/web/security/oidc/StandardOidcIdentityProviderGroovyTest.groovy
@@ -412,9 +412,27 @@ class StandardOidcIdentityProviderGroovyTest extends
GroovyTestCase {
}
@Test
+ void
testConvertOIDCTokenToLoginAuthenticationTokenShouldHandleNoEmailClaimHasFallbackClaims()
{
+ // Arrange
+ StandardOidcIdentityProvider soip =
buildIdentityProviderWithMockTokenValidator(["getOidcClaimIdentifyingUser":
"email", "getOidcFallbackClaimsIdentifyingUser": ["upn"] ])
+ String expectedUpn = "xxx@aaddomain";
+
+ OIDCTokenResponse mockResponse = mockOIDCTokenResponse(["email": null,
"upn": expectedUpn])
+ logger.info("OIDC Token Response with no email and upn:
${mockResponse.dump()}")
+
+ String loginToken =
soip.convertOIDCTokenToLoginAuthenticationToken(mockResponse)
+ logger.info("NiFi token create with upn: ${loginToken}")
+ // Assert
+ // Split JWT into components and decode Base64 to JSON
+ def (String contents, String expiration) =
loginToken.tokenize("\\[\\]")
+ logger.info("Token contents: ${contents} | Expiration: ${expiration}")
+ assert contents =~ "LoginAuthenticationToken for ${expectedUpn} issued
by https://accounts\\.issuer\\.com expiring at"
+ }
+
+ @Test
void
testConvertOIDCTokenToLoginAuthNTokenShouldHandleBlankIdentityAndNoEmailClaim()
{
// Arrange
- StandardOidcIdentityProvider soip =
buildIdentityProviderWithMockTokenValidator(["getOidcClaimIdentifyingUser":
"non-existent-claim"])
+ StandardOidcIdentityProvider soip =
buildIdentityProviderWithMockTokenValidator(["getOidcClaimIdentifyingUser":
"non-existent-claim", "getOidcFallbackClaimsIdentifyingUser": [] ])
OIDCTokenResponse mockResponse = mockOIDCTokenResponse(["email": null])
logger.info("OIDC Token Response: ${mockResponse.dump()}")