mirror of
https://github.com/apache/nifi.git
synced 2025-02-06 18:18:27 +00:00
NIFI-13998 Add OIDC Client Credentials Flow support to NiFi CLI (#9512)
Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
parent
21e7eef660
commit
b7e49bfac1
@ -46,6 +46,7 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.VersionsClient;
|
||||
import org.apache.nifi.toolkit.cli.impl.client.nifi.impl.JerseyNiFiClient;
|
||||
import org.apache.nifi.toolkit.cli.impl.client.nifi.impl.request.BasicAuthRequestConfig;
|
||||
import org.apache.nifi.toolkit.cli.impl.client.nifi.impl.request.BearerTokenRequestConfig;
|
||||
import org.apache.nifi.toolkit.cli.impl.client.nifi.impl.request.OIDCClientCredentialsRequestConfig;
|
||||
import org.apache.nifi.toolkit.cli.impl.client.nifi.impl.request.ProxiedEntityRequestConfig;
|
||||
import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
|
||||
|
||||
@ -83,6 +84,10 @@ public class NiFiClientFactory implements ClientFactory<NiFiClient> {
|
||||
final String basicAuthUsername = properties.getProperty(CommandOption.BASIC_AUTH_USER.getLongName());
|
||||
final String basicAuthPassword = properties.getProperty(CommandOption.BASIC_AUTH_PASSWORD.getLongName());
|
||||
|
||||
final String oidcTokenUrl = properties.getProperty(CommandOption.OIDC_TOKEN_URL.getLongName());
|
||||
final String oidcClientId = properties.getProperty(CommandOption.OIDC_CLIENT_ID.getLongName());
|
||||
final String oidcClientSecret = properties.getProperty(CommandOption.OIDC_CLIENT_SECRET.getLongName());
|
||||
|
||||
final String bearerToken = properties.getProperty(CommandOption.BEARER_TOKEN.getLongName());
|
||||
|
||||
final boolean secureUrl = url.startsWith("https");
|
||||
@ -118,6 +123,16 @@ public class NiFiClientFactory implements ClientFactory<NiFiClient> {
|
||||
+ " is required when specifying " + CommandOption.BASIC_AUTH_PASSWORD.getLongName());
|
||||
}
|
||||
|
||||
if (!StringUtils.isBlank(oidcTokenUrl) && StringUtils.isBlank(oidcClientId)) {
|
||||
throw new MissingOptionException(CommandOption.OIDC_CLIENT_ID.getLongName()
|
||||
+ " is required when specifying " + CommandOption.OIDC_TOKEN_URL.getLongName());
|
||||
}
|
||||
|
||||
if (!StringUtils.isBlank(oidcTokenUrl) && StringUtils.isBlank(oidcClientSecret)) {
|
||||
throw new MissingOptionException(CommandOption.OIDC_CLIENT_SECRET.getLongName()
|
||||
+ " is required when specifying " + CommandOption.OIDC_TOKEN_URL.getLongName());
|
||||
}
|
||||
|
||||
final NiFiClientConfig.Builder clientConfigBuilder = new NiFiClientConfig.Builder()
|
||||
.baseUrl(url);
|
||||
|
||||
@ -179,6 +194,9 @@ public class NiFiClientFactory implements ClientFactory<NiFiClient> {
|
||||
} else if (!StringUtils.isBlank(basicAuthUsername) && !StringUtils.isBlank(basicAuthPassword)) {
|
||||
final RequestConfig basicAuthConfig = new BasicAuthRequestConfig(basicAuthUsername, basicAuthPassword);
|
||||
return new NiFiClientWithRequestConfig(client, basicAuthConfig);
|
||||
} else if (!StringUtils.isBlank(oidcTokenUrl) && !StringUtils.isBlank(oidcClientId) && !StringUtils.isBlank(oidcClientSecret)) {
|
||||
final RequestConfig oidcAuthConfig = new OIDCClientCredentialsRequestConfig(clientConfigBuilder.build(), oidcTokenUrl, oidcClientId, oidcClientSecret);
|
||||
return new NiFiClientWithRequestConfig(client, oidcAuthConfig);
|
||||
} else {
|
||||
return client;
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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
|
||||
*
|
||||
* http://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.apache.nifi.toolkit.cli.impl.client.nifi.impl.request;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.ws.rs.client.ClientBuilder;
|
||||
import jakarta.ws.rs.client.Entity;
|
||||
import jakarta.ws.rs.client.WebTarget;
|
||||
import jakarta.ws.rs.core.Form;
|
||||
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientConfig;
|
||||
import org.apache.nifi.toolkit.cli.impl.client.nifi.RequestConfig;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Implementation of RequestConfig when using the OAuth Client Credentials Flow
|
||||
*/
|
||||
public class OIDCClientCredentialsRequestConfig implements RequestConfig {
|
||||
|
||||
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||
public static final String BEARER = "Bearer";
|
||||
|
||||
private final String token;
|
||||
|
||||
public OIDCClientCredentialsRequestConfig(NiFiClientConfig niFiClientConfig, final String oidcTokenUrl, final String oidcClientId, final String oidcClientSecret) {
|
||||
Objects.requireNonNull(oidcTokenUrl);
|
||||
Objects.requireNonNull(oidcClientId);
|
||||
Objects.requireNonNull(oidcClientSecret);
|
||||
Objects.requireNonNull(niFiClientConfig);
|
||||
|
||||
final SSLContext sslContext = niFiClientConfig.getSslContext();
|
||||
final HostnameVerifier hostnameVerifier = niFiClientConfig.getHostnameVerifier();
|
||||
|
||||
final ClientBuilder clientBuilder = ClientBuilder.newBuilder();
|
||||
if (sslContext != null) {
|
||||
clientBuilder.sslContext(sslContext);
|
||||
}
|
||||
if (hostnameVerifier != null) {
|
||||
clientBuilder.hostnameVerifier(hostnameVerifier);
|
||||
}
|
||||
|
||||
final Form form = new Form();
|
||||
form.param("grant_type", "client_credentials");
|
||||
form.param("client_id", oidcClientId);
|
||||
form.param("client_secret", oidcClientSecret);
|
||||
|
||||
final WebTarget target = clientBuilder.build().target(oidcTokenUrl);
|
||||
final String response = target.request().post(Entity.form(form), String.class);
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
this.token = mapper.readTree(response).get("access_token").textValue();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getHeaders() {
|
||||
final Map<String, String> headers = new HashMap<>();
|
||||
headers.put(AUTHORIZATION_HEADER, BEARER + " " + token);
|
||||
return headers;
|
||||
}
|
||||
}
|
@ -177,6 +177,10 @@ public enum CommandOption {
|
||||
USERNAME("usr", "username", "The username for authentication when obtaining an access token", true),
|
||||
PASSWORD("pwd", "password", "The password for authentication when obtaining an access token", true),
|
||||
|
||||
OIDC_TOKEN_URL("oidctokenurl", "oidcTokenUrl", "The OIDC URL to access the token endpoint for the OAuth Client Credentials Flow", true),
|
||||
OIDC_CLIENT_ID("oidcid", "oidcClientId", "The Client ID for the OAuth Client Credentials Flow", true),
|
||||
OIDC_CLIENT_SECRET("oidcsecret", "oidcClientSecret", "The Client Secret for the OAuth Client Credentials Flow", true),
|
||||
|
||||
KERBEROS_PRINCIPAL("krbPr", "kerberosPrincipal", "The kerberos principal", true),
|
||||
KERBEROS_KEYTAB("krbKt", "kerberosKeytab", "The keytab for a kerberos principal", true, true),
|
||||
KERBEROS_PASSWORD("krbPw", "kerberosPassword", "The password for a kerberos principal", true),
|
||||
@ -207,7 +211,6 @@ public enum CommandOption {
|
||||
this.isFile = isFile;
|
||||
}
|
||||
|
||||
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user