Skip to content

Commit ea35791

Browse files
committed
NIFI-15161 - Add support for Azure Federated Identity Credentials in Storage components
1 parent 8450ec7 commit ea35791

File tree

15 files changed

+669
-7
lines changed

15 files changed

+669
-7
lines changed

nifi-extension-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@
2626
<artifactId>nifi-utils</artifactId>
2727
</dependency>
2828

29+
<!-- OAuth2 Access Token Provider API for Web Identity (OIDC) support -->
30+
<dependency>
31+
<groupId>org.apache.nifi</groupId>
32+
<artifactId>nifi-oauth2-provider-api</artifactId>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.apache.nifi</groupId>
36+
<artifactId>nifi-web-client-api</artifactId>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.apache.nifi</groupId>
40+
<artifactId>nifi-web-client-provider-api</artifactId>
41+
</dependency>
42+
2943
<dependency>
3044
<groupId>org.apache.nifi</groupId>
3145
<artifactId>nifi-service-utils</artifactId>

nifi-extension-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/AzureStorageUtils.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.nifi.context.PropertyContext;
2626
import org.apache.nifi.expression.ExpressionLanguageScope;
2727
import org.apache.nifi.flowfile.FlowFile;
28+
import org.apache.nifi.services.azure.AzureIdentityFederationTokenProvider;
2829
import org.apache.nifi.processor.exception.ProcessException;
2930
import org.apache.nifi.processor.util.StandardValidators;
3031
import org.apache.nifi.proxy.ProxyConfiguration;
@@ -85,7 +86,8 @@ public final class AzureStorageUtils {
8586
AzureStorageCredentialsType.ACCOUNT_KEY,
8687
AzureStorageCredentialsType.SAS_TOKEN,
8788
AzureStorageCredentialsType.MANAGED_IDENTITY,
88-
AzureStorageCredentialsType.SERVICE_PRINCIPAL))
89+
AzureStorageCredentialsType.SERVICE_PRINCIPAL,
90+
AzureStorageCredentialsType.ACCESS_TOKEN))
8991
.defaultValue(AzureStorageCredentialsType.SAS_TOKEN)
9092
.build();
9193

@@ -252,6 +254,14 @@ public final class AzureStorageUtils {
252254
.dependsOn(CREDENTIALS_TYPE, AzureStorageCredentialsType.SERVICE_PRINCIPAL)
253255
.build();
254256

257+
public static final PropertyDescriptor OAUTH2_ACCESS_TOKEN_PROVIDER = new PropertyDescriptor.Builder()
258+
.name("Azure Identity Federation Token Provider")
259+
.description("Controller Service that exchanges workload identity tokens for Azure AD access tokens.")
260+
.identifiesControllerService(AzureIdentityFederationTokenProvider.class)
261+
.required(true)
262+
.dependsOn(CREDENTIALS_TYPE, AzureStorageCredentialsType.ACCESS_TOKEN)
263+
.build();
264+
255265
private AzureStorageUtils() {
256266
// do not instantiate
257267
}

nifi-extension-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/StandardAzureCredentialsControllerService.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import org.apache.nifi.migration.PropertyConfiguration;
3131
import org.apache.nifi.processor.exception.ProcessException;
3232
import org.apache.nifi.processor.util.StandardValidators;
33+
import org.apache.nifi.services.azure.util.OAuth2AccessTokenAdapter;
34+
import reactor.core.publisher.Mono;
3335

3436
import java.util.List;
3537

@@ -47,12 +49,15 @@ public class StandardAzureCredentialsControllerService extends AbstractControlle
4749
public static AllowableValue MANAGED_IDENTITY = new AllowableValue("managed-identity",
4850
"Managed Identity",
4951
"Azure Virtual Machine Managed Identity (it can only be used when NiFi is running on Azure)");
52+
public static AllowableValue OAUTH2 = new AllowableValue("oauth2-access-token",
53+
"OAuth2 Access Token",
54+
"Uses an OAuth2 Access Token Provider controller service to obtain access tokens for Azure clients.");
5055
public static final PropertyDescriptor CREDENTIAL_CONFIGURATION_STRATEGY = new PropertyDescriptor.Builder()
5156
.name("Credential Configuration Strategy")
5257
.expressionLanguageSupported(ExpressionLanguageScope.NONE)
5358
.required(true)
5459
.sensitive(false)
55-
.allowableValues(DEFAULT_CREDENTIAL, MANAGED_IDENTITY)
60+
.allowableValues(DEFAULT_CREDENTIAL, MANAGED_IDENTITY, OAUTH2)
5661
.defaultValue(DEFAULT_CREDENTIAL)
5762
.build();
5863

@@ -67,9 +72,18 @@ public class StandardAzureCredentialsControllerService extends AbstractControlle
6772
.dependsOn(CREDENTIAL_CONFIGURATION_STRATEGY, MANAGED_IDENTITY)
6873
.build();
6974

75+
public static final PropertyDescriptor OAUTH2_ACCESS_TOKEN_PROVIDER = new PropertyDescriptor.Builder()
76+
.name("Azure Identity Federation Token Provider")
77+
.description("Controller Service used to obtain Azure access tokens via workload identity federation.")
78+
.identifiesControllerService(AzureIdentityFederationTokenProvider.class)
79+
.required(true)
80+
.dependsOn(CREDENTIAL_CONFIGURATION_STRATEGY, OAUTH2)
81+
.build();
82+
7083
private static final List<PropertyDescriptor> PROPERTY_DESCRIPTORS = List.of(
7184
CREDENTIAL_CONFIGURATION_STRATEGY,
72-
MANAGED_IDENTITY_CLIENT_ID
85+
MANAGED_IDENTITY_CLIENT_ID,
86+
OAUTH2_ACCESS_TOKEN_PROVIDER
7387
);
7488

7589
private TokenCredential credentials;
@@ -92,6 +106,8 @@ public void onConfigured(final ConfigurationContext context) {
92106
credentials = getDefaultAzureCredential();
93107
} else if (MANAGED_IDENTITY.getValue().equals(configurationStrategy)) {
94108
credentials = getManagedIdentityCredential(context);
109+
} else if (OAUTH2.getValue().equals(configurationStrategy)) {
110+
credentials = getOAuth2Credential(context);
95111
} else {
96112
final String errorMsg = String.format("Configuration Strategy [%s] not recognized", configurationStrategy);
97113
getLogger().error(errorMsg);
@@ -117,6 +133,13 @@ private TokenCredential getManagedIdentityCredential(final ConfigurationContext
117133
.build();
118134
}
119135

136+
private TokenCredential getOAuth2Credential(final ConfigurationContext context) {
137+
final AzureIdentityFederationTokenProvider oauth2AccessTokenProvider = context.getProperty(OAUTH2_ACCESS_TOKEN_PROVIDER)
138+
.asControllerService(AzureIdentityFederationTokenProvider.class);
139+
return tokenRequestContext -> Mono.fromSupplier(() ->
140+
OAuth2AccessTokenAdapter.toAzureAccessToken(oauth2AccessTokenProvider.getAccessDetails()));
141+
}
142+
120143
@Override
121144
public String toString() {
122145
return "StandardAzureCredentialsControllerService[id=" + getIdentifier() + "]";

0 commit comments

Comments
 (0)