mirror of
https://github.com/apache/nifi.git
synced 2025-03-03 07:59:15 +00:00
NIFI-7526 Updated code to use the new helper library for OkHttp.
Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com> This closes #4331.
This commit is contained in:
parent
633fd8883d
commit
83fd4ca291
@ -94,5 +94,11 @@
|
|||||||
<artifactId>jetty-server</artifactId>
|
<artifactId>jetty-server</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.nifi</groupId>
|
||||||
|
<artifactId>nifi-web-utils</artifactId>
|
||||||
|
<version>1.12.0-SNAPSHOT</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package org.apache.nifi.oauth2;
|
package org.apache.nifi.oauth2;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import okhttp3.FormBody;
|
import okhttp3.FormBody;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
@ -29,6 +30,8 @@ import org.apache.nifi.components.PropertyDescriptor;
|
|||||||
import org.apache.nifi.controller.AbstractControllerService;
|
import org.apache.nifi.controller.AbstractControllerService;
|
||||||
import org.apache.nifi.controller.ConfigurationContext;
|
import org.apache.nifi.controller.ConfigurationContext;
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
|
import org.apache.nifi.security.util.OkHttpClientUtils;
|
||||||
|
import org.apache.nifi.security.util.TlsConfiguration;
|
||||||
import org.apache.nifi.ssl.SSLContextService;
|
import org.apache.nifi.ssl.SSLContextService;
|
||||||
import org.apache.nifi.security.util.SslContextFactory;
|
import org.apache.nifi.security.util.SslContextFactory;
|
||||||
import org.apache.nifi.util.StringUtils;
|
import org.apache.nifi.util.StringUtils;
|
||||||
@ -36,8 +39,7 @@ import org.apache.nifi.util.StringUtils;
|
|||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import static org.apache.nifi.oauth2.Util.parseTokenResponse;
|
|
||||||
|
|
||||||
@Tags({"oauth2", "provider", "authorization" })
|
@Tags({"oauth2", "provider", "authorization" })
|
||||||
@CapabilityDescription("This controller service provides a way of working with access and refresh tokens via the " +
|
@CapabilityDescription("This controller service provides a way of working with access and refresh tokens via the " +
|
||||||
@ -88,12 +90,9 @@ public class OAuth2TokenProviderImpl extends AbstractControllerService implement
|
|||||||
private OkHttpClient.Builder getClientBuilder() {
|
private OkHttpClient.Builder getClientBuilder() {
|
||||||
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
|
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
|
||||||
|
|
||||||
if (sslContext != null) {
|
if (sslContextService != null) {
|
||||||
try {
|
final TlsConfiguration tlsConfiguration = sslContextService.createTlsConfiguration();
|
||||||
Util.setSslSocketFactory(clientBuilder, sslContextService, sslContext, false);
|
OkHttpClientUtils.applyTlsToOkHttpClientBuilder(tlsConfiguration, clientBuilder);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ProcessException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientBuilder;
|
return clientBuilder;
|
||||||
@ -152,4 +151,35 @@ public class OAuth2TokenProviderImpl extends AbstractControllerService implement
|
|||||||
|
|
||||||
return executePost(client, newRequest);
|
return executePost(client, newRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
public static final String KEY_ACCESS_TOKEN = "access_token";
|
||||||
|
public static final String KEY_REFRESH_TOKEN = "refresh_token";
|
||||||
|
public static final String KEY_EXPIRES = "expires_in";
|
||||||
|
public static final String KEY_TOKEN_TYPE = "token_type";
|
||||||
|
public static final String KEY_SCOPE = "scope";
|
||||||
|
|
||||||
|
public AccessToken parseTokenResponse(String rawResponse) {
|
||||||
|
try {
|
||||||
|
Map<String, Object> parsed = MAPPER.readValue(rawResponse, Map.class);
|
||||||
|
String accessToken = (String)parsed.get(KEY_ACCESS_TOKEN);
|
||||||
|
String refreshToken = (String)parsed.get(KEY_REFRESH_TOKEN);
|
||||||
|
Integer expires = (Integer)parsed.get(KEY_EXPIRES);
|
||||||
|
String tokenType = (String)parsed.get(KEY_TOKEN_TYPE);
|
||||||
|
String scope = (String)parsed.get(KEY_SCOPE);
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(accessToken)) {
|
||||||
|
throw new Exception(String.format("Missing value for %s", KEY_ACCESS_TOKEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(tokenType)) {
|
||||||
|
throw new Exception(String.format("Missing value for %s", KEY_TOKEN_TYPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AccessToken(accessToken, refreshToken, tokenType, expires, scope);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new ProcessException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.oauth2;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
|
||||||
import org.apache.nifi.ssl.SSLContextService;
|
|
||||||
import org.apache.nifi.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.net.ssl.KeyManager;
|
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
|
||||||
import javax.net.ssl.TrustManager;
|
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
|
||||||
import javax.net.ssl.X509TrustManager;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.KeyManagementException;
|
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.security.KeyStoreException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.UnrecoverableKeyException;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Util {
|
|
||||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This code as taken from the InvokeHttp processor from Apache NiFi 1.10-SNAPSHOT found here:
|
|
||||||
*
|
|
||||||
* https://github.com/apache/nifi/blob/1cadc722229ad50cf569ee107eaeeb95dc216ea2/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
|
|
||||||
*/
|
|
||||||
public static void setSslSocketFactory(OkHttpClient.Builder okHttpClientBuilder, SSLContextService sslService, SSLContext sslContext, boolean setAsSocketFactory)
|
|
||||||
throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
|
|
||||||
|
|
||||||
final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
|
||||||
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
|
|
||||||
// initialize the KeyManager array to null and we will overwrite later if a keystore is loaded
|
|
||||||
KeyManager[] keyManagers = null;
|
|
||||||
|
|
||||||
// we will only initialize the keystore if properties have been supplied by the SSLContextService
|
|
||||||
if (sslService.isKeyStoreConfigured()) {
|
|
||||||
final String keystoreLocation = sslService.getKeyStoreFile();
|
|
||||||
final String keystorePass = sslService.getKeyStorePassword();
|
|
||||||
final String keystoreType = sslService.getKeyStoreType();
|
|
||||||
|
|
||||||
// prepare the keystore
|
|
||||||
final KeyStore keyStore = KeyStore.getInstance(keystoreType);
|
|
||||||
|
|
||||||
try (FileInputStream keyStoreStream = new FileInputStream(keystoreLocation)) {
|
|
||||||
keyStore.load(keyStoreStream, keystorePass.toCharArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
keyManagerFactory.init(keyStore, keystorePass.toCharArray());
|
|
||||||
keyManagers = keyManagerFactory.getKeyManagers();
|
|
||||||
}
|
|
||||||
|
|
||||||
// we will only initialize the truststure if properties have been supplied by the SSLContextService
|
|
||||||
if (sslService.isTrustStoreConfigured()) {
|
|
||||||
// load truststore
|
|
||||||
final String truststoreLocation = sslService.getTrustStoreFile();
|
|
||||||
final String truststorePass = sslService.getTrustStorePassword();
|
|
||||||
final String truststoreType = sslService.getTrustStoreType();
|
|
||||||
|
|
||||||
KeyStore truststore = KeyStore.getInstance(truststoreType);
|
|
||||||
truststore.load(new FileInputStream(truststoreLocation), truststorePass.toCharArray());
|
|
||||||
trustManagerFactory.init(truststore);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
TrustManagerFactory.getTrustManagers returns a trust manager for each type of trust material. Since we are getting a trust manager factory that uses "X509"
|
|
||||||
as it's trust management algorithm, we are able to grab the first (and thus the most preferred) and use it as our x509 Trust Manager
|
|
||||||
https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/TrustManagerFactory.html#getTrustManagers--
|
|
||||||
*/
|
|
||||||
final X509TrustManager x509TrustManager;
|
|
||||||
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
|
|
||||||
if (trustManagers[0] != null) {
|
|
||||||
x509TrustManager = (X509TrustManager) trustManagers[0];
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException("List of trust managers is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
// if keystore properties were not supplied, the keyManagers array will be null
|
|
||||||
sslContext.init(keyManagers, trustManagerFactory.getTrustManagers(), null);
|
|
||||||
|
|
||||||
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
|
||||||
okHttpClientBuilder.sslSocketFactory(sslSocketFactory, x509TrustManager);
|
|
||||||
if (setAsSocketFactory) {
|
|
||||||
okHttpClientBuilder.socketFactory(sslSocketFactory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String KEY_ACCESS_TOKEN = "access_token";
|
|
||||||
public static final String KEY_REFRESH_TOKEN = "refresh_token";
|
|
||||||
public static final String KEY_EXPIRES = "expires_in";
|
|
||||||
public static final String KEY_TOKEN_TYPE = "token_type";
|
|
||||||
public static final String KEY_SCOPE = "scope";
|
|
||||||
|
|
||||||
public static AccessToken parseTokenResponse(String rawResponse) {
|
|
||||||
try {
|
|
||||||
Map<String, Object> parsed = MAPPER.readValue(rawResponse, Map.class);
|
|
||||||
String accessToken = (String)parsed.get(KEY_ACCESS_TOKEN);
|
|
||||||
String refreshToken = (String)parsed.get(KEY_REFRESH_TOKEN);
|
|
||||||
Integer expires = (Integer)parsed.get(KEY_EXPIRES);
|
|
||||||
String tokenType = (String)parsed.get(KEY_TOKEN_TYPE);
|
|
||||||
String scope = (String)parsed.get(KEY_SCOPE);
|
|
||||||
|
|
||||||
if (StringUtils.isEmpty(accessToken)) {
|
|
||||||
throw new Exception(String.format("Missing value for %s", KEY_ACCESS_TOKEN));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isEmpty(tokenType)) {
|
|
||||||
throw new Exception(String.format("Missing value for %s", KEY_TOKEN_TYPE));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new AccessToken(accessToken, refreshToken, tokenType, expires, scope);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new ProcessException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user