You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by is...@apache.org on 2021/07/04 16:22:16 UTC

[airavata-data-lake] branch master updated: add agent authentication

This is an automated email from the ASF dual-hosted git repository.

isjarana pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-data-lake.git


The following commit(s) were added to refs/heads/master by this push:
     new c97816f  add agent authentication
     new 5f1a867  Merge pull request #12 from isururanawaka/workflow_merge
c97816f is described below

commit c97816f99dcd3b77aecbf1629244cf504535da1c
Author: Isuru Ranawaka <ir...@gmail.com>
AuthorDate: Sun Jul 4 12:21:25 2021 -0400

    add agent authentication
---
 .../java/org/apache/airavata/drms/api/Client.java  | 73 ++++++++++-------
 .../drms/api/interceptors/Authenticator.java       | 91 ++++++++++++++++------
 .../drms-stubs/src/main/proto/Common.proto         |  8 ++
 3 files changed, 122 insertions(+), 50 deletions(-)

diff --git a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/Client.java b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/Client.java
index ece993c..24f8c34 100644
--- a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/Client.java
+++ b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/Client.java
@@ -20,6 +20,8 @@ import com.google.protobuf.Struct;
 import com.google.protobuf.util.JsonFormat;
 import io.grpc.ManagedChannel;
 import io.grpc.ManagedChannelBuilder;
+import org.apache.airavata.datalake.drms.AuthCredentialType;
+import org.apache.airavata.datalake.drms.AuthenticatedUser;
 import org.apache.airavata.datalake.drms.DRMSServiceAuthToken;
 import org.apache.airavata.datalake.drms.resource.GenericResource;
 import org.apache.airavata.datalake.drms.storage.*;
@@ -29,8 +31,9 @@ import org.json.JSONObject;
 import org.json.JSONTokener;
 
 import java.io.FileInputStream;
-import java.util.ArrayList;
-import java.util.List;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.UUID;
 
 public class Client {
     public static void main(String ar[]) {
@@ -50,7 +53,7 @@ public class Client {
         DRMSServiceAuthToken authToken = DRMSServiceAuthToken.newBuilder().
                 setAccessToken(token).build();
 
-//
+
 //        StorageCreateRequest request = StorageCreateRequest.newBuilder().setAuthToken(authToken).
 //                setStorage(AnyStorage.newBuilder().setSshStorage(SSHStorage.newBuilder()
 //                        .setStorageId("qwerft-rftgyhu-oplmnj")
@@ -60,7 +63,6 @@ public class Client {
 //                        .build()).
 //                build();
 //        resourceClient.createStorage(request);
-//
 
 
         StorageSearchRequest storageSearchRequest = StorageSearchRequest
@@ -135,20 +137,27 @@ public class Client {
 //
 //        resourceServiceBlockingStub.fetchChildResources(childResourceFetchRequest);
 
-//        String id = UUID.randomUUID().toString();
-//
-//        GenericResource genericResource = GenericResource
-//                .newBuilder()
-//                .setResourceId(id)
-//                .setType("COLLECTION")
-//                .setResourceName("COLLECTION_SDK_TEST_TWO")
-//                .build();
-//
-//        ResourceCreateRequest resourceCreateRequest = ResourceCreateRequest.newBuilder()
-//                .setAuthToken(authToken)
-//                .setResource(genericResource)
+        String id = UUID.randomUUID().toString();
+
+        GenericResource genericResource = GenericResource
+                .newBuilder()
+                .setResourceId(id)
+                .setType("COLLECTION")
+                .setResourceName("COLLECTION_SDK_TEST_TWO")
+                .build();
+
+
+//        DRMSServiceAuthToken drmsServiceAuthToken = DRMSServiceAuthToken.newBuilder()
+//                .setAccessToken(getServiceAccountToken())
+//                .setAuthenticatedUser(AuthenticatedUser.newBuilder().setUsername("isjarana@iu.edu")
+//                        .setTenantId("custos-whedmgamitu357p4wuke-10002708"))
+//                .setAuthCredentialType(AuthCredentialType.AGENT_ACCOUNT_CREDENTIAL)
 //                .build();
-//        resourceServiceBlockingStub.createResource(resourceCreateRequest);
+        ResourceCreateRequest resourceCreateRequest = ResourceCreateRequest.newBuilder()
+                .setAuthToken(authToken)
+                .setResource(genericResource)
+                .build();
+        resourceServiceBlockingStub.createResource(resourceCreateRequest);
 
 
 //        System.out.println(authToken.getAccessToken());
@@ -224,19 +233,18 @@ public class Client {
 //
 //            resourceServiceBlockingStub.addResourceMetadata(addResourceMetadataRequest);
 
-        FetchResourceMetadataRequest addResourceMetadataRequest = FetchResourceMetadataRequest
-                .newBuilder()
-                .setAuthToken(authToken)
-                .setResourceId("custos-whedmgamitu357p4wuke-10002708_132068.39999997616")
-                .setType("FILE")
-                .build();
-
-        resourceServiceBlockingStub.fetchResourceMetadata(addResourceMetadataRequest);
-
+//        FetchResourceMetadataRequest addResourceMetadataRequest = FetchResourceMetadataRequest
+//                .newBuilder()
+//                .setAuthToken(authToken)
+//                .setResourceId("custos-whedmgamitu357p4wuke-10002708_132068.39999997616")
+//                .setType("FILE")
+//                .build();
+//
+//        resourceServiceBlockingStub.fetchResourceMetadata(addResourceMetadataRequest);
 
 
         } catch (Exception ex) {
-             ex.printStackTrace();
+            ex.printStackTrace();
         }
 
 
@@ -259,4 +267,15 @@ public class Client {
         }
         return null;
     }
+
+    private static String getServiceAccountToken() {
+        try {
+
+            return Base64.getEncoder().encodeToString(("file-listener-service-account" + ":" + "yyvQs3bKk2xp6W9YwuRQO3PvZrXruwRh0e0nR5kR")
+                    .getBytes(StandardCharsets.UTF_8));
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+        return null;
+    }
 }
diff --git a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/interceptors/Authenticator.java b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/interceptors/Authenticator.java
index e793e41..f2eae42 100644
--- a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/interceptors/Authenticator.java
+++ b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/interceptors/Authenticator.java
@@ -3,18 +3,23 @@ package org.apache.airavata.drms.api.interceptors;
 import com.google.protobuf.Descriptors;
 import com.google.protobuf.GeneratedMessageV3;
 import com.google.protobuf.Message;
+import com.google.protobuf.Struct;
 import io.grpc.Metadata;
+import org.apache.airavata.datalake.drms.AuthCredentialType;
 import org.apache.airavata.datalake.drms.AuthenticatedUser;
 import org.apache.airavata.datalake.drms.DRMSServiceAuthToken;
 import org.apache.custos.clients.CustosClientProvider;
+import org.apache.custos.iam.service.UserRepresentation;
 import org.apache.custos.identity.management.client.IdentityManagementClient;
 import org.apache.custos.identity.service.User;
+import org.apache.custos.user.management.client.UserManagementClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.io.IOException;
+import java.util.Base64;
 import java.util.Optional;
 
 @Component
@@ -27,33 +32,16 @@ public class Authenticator implements ServiceInterceptor {
 
     @Override
     public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) throws IOException {
-        IdentityManagementClient identityManagementClient = custosClientProvider.getIdentityManagementClient();
-        Optional<String> token = getAccessToken(msg, headers);
-        User user = identityManagementClient.getUser(token.get());
-        AuthenticatedUser authenticatedUser = AuthenticatedUser.newBuilder()
-                .setUsername(user.getUsername())
-                .setFirstName(user.getFirstName())
-                .setLastName(user.getLastName())
-                .setEmailAddress(user.getEmailAddress())
-                .setTenantId(user.getClientId())
-                .build();
-        return (ReqT) setAuthenticatedUser(msg, authenticatedUser);
+        Optional<AuthenticatedUser> authenticatorOptional = getAuthenticatedUser(msg, headers);
+        if (authenticatorOptional.isPresent()) {
+            return (ReqT) setAuthenticatedUser(msg, authenticatorOptional.get());
+        } else {
+            throw new RuntimeException("Unauthenticated user");
+        }
 
     }
 
 
-    private Optional<String> getAccessToken(Object msg, Metadata headers) {
-        Optional<String> tokenHeaders = getTokenFromHeader(headers);
-        if (tokenHeaders.isEmpty()) {
-            Descriptors.FieldDescriptor fieldDescriptor =
-                    ((com.google.protobuf.GeneratedMessageV3) msg).getDescriptorForType().findFieldByName("auth_token");
-            Object value = ((com.google.protobuf.GeneratedMessageV3) msg).getField(fieldDescriptor);
-            DRMSServiceAuthToken drmsServiceAuthToken = (DRMSServiceAuthToken) value;
-            return Optional.ofNullable(drmsServiceAuthToken.getAccessToken());
-        }
-        return Optional.ofNullable(tokenHeaders.get());
-    }
-
     private Object setAuthenticatedUser(Object msg, AuthenticatedUser user) {
 
         Descriptors.FieldDescriptor fieldDescriptor =
@@ -79,4 +67,61 @@ public class Authenticator implements ServiceInterceptor {
         return Optional.ofNullable(token.trim());
     }
 
+    public Optional<AuthenticatedUser> getAuthenticatedUser(Object msg, Metadata headers) throws IOException {
+        IdentityManagementClient identityManagementClient = custosClientProvider.getIdentityManagementClient();
+        UserManagementClient userManagementClient = custosClientProvider.getUserManagementClient();
+        Optional<String> tokenHeaders = getTokenFromHeader(headers);
+        if (tokenHeaders.isEmpty()) {
+            //Assume java client is used
+            Descriptors.FieldDescriptor fieldDescriptor =
+                    ((com.google.protobuf.GeneratedMessageV3) msg).getDescriptorForType().findFieldByName("auth_token");
+            Object value = ((com.google.protobuf.GeneratedMessageV3) msg).getField(fieldDescriptor);
+            DRMSServiceAuthToken drmsServiceAuthToken = (DRMSServiceAuthToken) value;
+            if (drmsServiceAuthToken.getAuthCredentialType().equals(AuthCredentialType.UNKNOWN) ||
+                    drmsServiceAuthToken.getAuthCredentialType().equals(AuthCredentialType.USER_CREDENTIAL)) {
+                String accessToken = drmsServiceAuthToken.getAccessToken();
+                User user = identityManagementClient.getUser(accessToken);
+                return Optional.ofNullable(AuthenticatedUser.newBuilder()
+                        .setUsername(user.getUsername())
+                        .setFirstName(user.getFirstName())
+                        .setLastName(user.getLastName())
+                        .setEmailAddress(user.getEmailAddress())
+                        .setTenantId(user.getClientId())
+                        .build());
+            } else if (drmsServiceAuthToken.getAuthCredentialType()
+                    .equals(AuthCredentialType.AGENT_ACCOUNT_CREDENTIAL)) {
+                //Agents use service account to get access token
+                String accessToken = drmsServiceAuthToken.getAccessToken();
+                String decoded = new String(Base64.getDecoder().decode(accessToken));
+                String[] array = decoded.split(":");
+                String agentClientId = array[0];
+                String agentClientSec = array[1];
+                String username = drmsServiceAuthToken.getAuthenticatedUser().getUsername();
+                String tenantId = drmsServiceAuthToken.getAuthenticatedUser().getTenantId();
+                Struct struct = identityManagementClient
+                        .getAgentToken(tenantId, agentClientId, agentClientSec, "client_credentials", "");
+                if (struct.getFieldsMap().get("access_token").isInitialized()) {
+                    UserRepresentation user = userManagementClient.getUser(username, tenantId);
+                    return Optional.ofNullable(AuthenticatedUser.newBuilder()
+                            .setUsername(user.getUsername())
+                            .setFirstName(user.getFirstName())
+                            .setLastName(user.getLastName())
+                            .setEmailAddress(user.getEmail())
+                            .setTenantId(tenantId)
+                            .build());
+                }
+            }
+        } else {
+            //Assume rest clients always call with user token
+            User user = identityManagementClient.getUser(tokenHeaders.get());
+            return Optional.ofNullable(AuthenticatedUser.newBuilder()
+                    .setUsername(user.getUsername())
+                    .setFirstName(user.getFirstName())
+                    .setLastName(user.getLastName())
+                    .setEmailAddress(user.getEmailAddress())
+                    .setTenantId(user.getClientId())
+                    .build());
+        }
+        return Optional.empty();
+    }
 }
diff --git a/data-resource-management-service/drms-stubs/src/main/proto/Common.proto b/data-resource-management-service/drms-stubs/src/main/proto/Common.proto
index 1e980e7..604c1fd 100644
--- a/data-resource-management-service/drms-stubs/src/main/proto/Common.proto
+++ b/data-resource-management-service/drms-stubs/src/main/proto/Common.proto
@@ -34,5 +34,13 @@ message AuthenticatedUser  {
 message DRMSServiceAuthToken {
     string access_token = 1;
     AuthenticatedUser authenticated_user = 2;
+    AuthCredentialType auth_credential_type =3;
 }
 
+enum AuthCredentialType {
+    UNKNOWN = 0;
+    USER_CREDENTIAL = 1;
+    AGENT_ACCOUNT_CREDENTIAL = 2;
+}
+
+