From 515a88fe1f3be30a887eaaa3d5b1b50f811b3122 Mon Sep 17 00:00:00 2001 From: Parth Panchal <83201188+parthp2107@users.noreply.github.com> Date: Mon, 13 Jun 2022 17:15:19 +0530 Subject: [PATCH] Fixed#5364: added support for azure sso (#5365) --- .../openmetadata-java-client/pom.xml | 5 ++ .../security/AzureAuthenticationProvider.java | 74 +++++++++++++++++-- .../GoogleAuthenticationProvider.java | 2 +- .../AuthenticationProviderFactory.java | 2 + .../interfaces/AuthenticationProvider.java | 3 +- 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/openmetadata-clients/openmetadata-java-client/pom.xml b/openmetadata-clients/openmetadata-java-client/pom.xml index f43b3ae0ea4..e50d197eb4d 100644 --- a/openmetadata-clients/openmetadata-java-client/pom.xml +++ b/openmetadata-clients/openmetadata-java-client/pom.xml @@ -64,6 +64,11 @@ google-auth-library-oauth2-http 1.3.0 + + com.microsoft.azure + msal4j + 1.12.0 + junit diff --git a/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/AzureAuthenticationProvider.java b/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/AzureAuthenticationProvider.java index 1014130ce6f..cd950756152 100644 --- a/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/AzureAuthenticationProvider.java +++ b/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/AzureAuthenticationProvider.java @@ -13,26 +13,86 @@ package org.openmetadata.client.security; +import com.google.common.collect.ImmutableSet; +import com.microsoft.aad.msal4j.ClientCredentialFactory; +import com.microsoft.aad.msal4j.ClientCredentialParameters; +import com.microsoft.aad.msal4j.ConfidentialClientApplication; +import com.microsoft.aad.msal4j.IAuthenticationResult; +import com.microsoft.aad.msal4j.IClientCredential; import feign.RequestTemplate; +import java.io.IOException; +import java.util.Set; +import org.openmetadata.catalog.security.client.AzureSSOClientConfig; import org.openmetadata.catalog.services.connections.metadata.OpenMetadataServerConnection; import org.openmetadata.client.security.interfaces.AuthenticationProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class AzureAuthenticationProvider implements AuthenticationProvider { - @Override - public AuthenticationProvider create(OpenMetadataServerConnection iConfig) { - return null; + private static final Logger LOG = LoggerFactory.getLogger(AzureAuthenticationProvider.class); + private OpenMetadataServerConnection serverConfig; + private final AzureSSOClientConfig securityConfig; + private String generatedAuthToken; + private Long expirationTimeMillis; + + public AzureAuthenticationProvider(OpenMetadataServerConnection iConfig) { + if (!iConfig.getAuthProvider().equals(OpenMetadataServerConnection.AuthProvider.AZURE)) { + LOG.error("Required type to invoke is Azure for AzureAuthentication Provider"); + throw new RuntimeException("Required type to invoke is Azure for AzureAuthentication Provider"); + } + serverConfig = iConfig; + + securityConfig = (AzureSSOClientConfig) iConfig.getSecurityConfig(); + if (securityConfig == null) { + LOG.error("Security Config is missing, it is required"); + throw new RuntimeException("Security Config is missing, it is required"); + } + generatedAuthToken = ""; } @Override - public String authToken() { - return null; + public AuthenticationProvider create(OpenMetadataServerConnection iConfig) { + return new AzureAuthenticationProvider(iConfig); + } + + @Override + public String authToken() throws IOException { + IClientCredential credential = ClientCredentialFactory.createFromSecret(securityConfig.getClientSecret()); + ConfidentialClientApplication cca = + ConfidentialClientApplication.builder(securityConfig.getClientId(), credential) + .authority(securityConfig.getAuthority()) + .build(); + Set scope = ImmutableSet.of("api://" + securityConfig.getClientId() + "/.default"); + + ClientCredentialParameters parameters = ClientCredentialParameters.builder(scope).build(); + IAuthenticationResult result = cca.acquireToken(parameters).join(); + generatedAuthToken = result.accessToken(); + return generatedAuthToken; } @Override public String getAccessToken() { - return null; + return generatedAuthToken; } @Override - public void apply(RequestTemplate requestTemplate) {} + public void apply(RequestTemplate requestTemplate) { + if (requestTemplate.url().contains("version")) { + return; + } + if (requestTemplate.headers().containsKey("Authorization")) { + return; + } + // If first time, get the token + if (expirationTimeMillis == null || System.currentTimeMillis() >= expirationTimeMillis) { + try { + this.authToken(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + if (getAccessToken() != null) { + requestTemplate.header("Authorization", "Bearer " + getAccessToken()); + } + } } diff --git a/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/GoogleAuthenticationProvider.java b/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/GoogleAuthenticationProvider.java index c83b7e778f9..205c3500d67 100644 --- a/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/GoogleAuthenticationProvider.java +++ b/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/GoogleAuthenticationProvider.java @@ -61,7 +61,7 @@ public class GoogleAuthenticationProvider implements AuthenticationProvider { try { String credPath = securityConfig.getSecretKey(); String targetAudience = securityConfig.getAudience(); - if ((credPath != null && credPath != "") && (targetAudience != null && targetAudience != "")) { + if ((credPath != null && !credPath.equals("")) && (targetAudience != null && !targetAudience.equals(""))) { ServiceAccountCredentials saCreds = ServiceAccountCredentials.fromStream(new FileInputStream(credPath)); saCreds = diff --git a/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/factory/AuthenticationProviderFactory.java b/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/factory/AuthenticationProviderFactory.java index f2ff2b27084..5d92f96f667 100644 --- a/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/factory/AuthenticationProviderFactory.java +++ b/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/factory/AuthenticationProviderFactory.java @@ -14,6 +14,7 @@ package org.openmetadata.client.security.factory; import org.openmetadata.catalog.services.connections.metadata.OpenMetadataServerConnection; +import org.openmetadata.client.security.AzureAuthenticationProvider; import org.openmetadata.client.security.GoogleAuthenticationProvider; import org.openmetadata.client.security.NoOpAuthenticationProvider; import org.openmetadata.client.security.OktaAuthenticationProvider; @@ -31,6 +32,7 @@ public class AuthenticationProviderFactory { case AUTH_0: case CUSTOM_OIDC: case AZURE: + return new AzureAuthenticationProvider(serverConfig); case OPENMETADATA: return null; } diff --git a/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/interfaces/AuthenticationProvider.java b/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/interfaces/AuthenticationProvider.java index 1f83aaf37ee..11a08bc2776 100644 --- a/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/interfaces/AuthenticationProvider.java +++ b/openmetadata-clients/openmetadata-java-client/src/main/java/org/openmetadata/client/security/interfaces/AuthenticationProvider.java @@ -14,12 +14,13 @@ package org.openmetadata.client.security.interfaces; import feign.RequestInterceptor; +import java.io.IOException; import org.openmetadata.catalog.services.connections.metadata.OpenMetadataServerConnection; public interface AuthenticationProvider extends RequestInterceptor { AuthenticationProvider create(OpenMetadataServerConnection iConfig); - String authToken(); + String authToken() throws IOException; String getAccessToken(); }