mirror of
				https://github.com/datahub-project/datahub.git
				synced 2025-10-31 10:49:00 +00:00 
			
		
		
		
	
		
			
	
	
		
			100 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
		
		
			
		
	
	
			100 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
|   | package client;
 | ||
|  | 
 | ||
|  | import com.fasterxml.jackson.databind.ObjectMapper;
 | ||
|  | import java.util.Objects;
 | ||
|  | import javax.annotation.Nonnull;
 | ||
|  | import lombok.extern.slf4j.Slf4j;
 | ||
|  | import org.apache.http.HttpEntity;
 | ||
|  | import org.apache.http.HttpStatus;
 | ||
|  | import org.apache.http.client.methods.CloseableHttpResponse;
 | ||
|  | import org.apache.http.client.methods.HttpPost;
 | ||
|  | import org.apache.http.entity.StringEntity;
 | ||
|  | import org.apache.http.impl.client.CloseableHttpClient;
 | ||
|  | import org.apache.http.impl.client.HttpClients;
 | ||
|  | import org.apache.http.util.EntityUtils;
 | ||
|  | import play.mvc.Http;
 | ||
|  | import com.datahub.authentication.Authentication;
 | ||
|  | 
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * This class is responsible for coordinating authentication with the backend Metadata Service.
 | ||
|  |  */
 | ||
|  | @Slf4j
 | ||
|  | public class AuthServiceClient {
 | ||
|  | 
 | ||
|  |   private static final String GENERATE_SESSION_TOKEN_ENDPOINT = "auth/generateSessionTokenForUser";
 | ||
|  |   private static final String ACCESS_TOKEN_FIELD = "accessToken";
 | ||
|  |   private static final String USER_ID_FIELD = "userId";
 | ||
|  | 
 | ||
|  |   private final String metadataServiceHost;
 | ||
|  |   private final Integer metadataServicePort;
 | ||
|  |   private final Boolean metadataServiceUseSsl;
 | ||
|  |   private final Authentication systemAuthentication;
 | ||
|  | 
 | ||
|  |   public AuthServiceClient(
 | ||
|  |       @Nonnull final String metadataServiceHost,
 | ||
|  |       @Nonnull final Integer metadataServicePort,
 | ||
|  |       @Nonnull final Boolean useSsl,
 | ||
|  |       @Nonnull final Authentication systemAuthentication) {
 | ||
|  |     this.metadataServiceHost = Objects.requireNonNull(metadataServiceHost);
 | ||
|  |     this.metadataServicePort = Objects.requireNonNull(metadataServicePort);
 | ||
|  |     this.metadataServiceUseSsl = Objects.requireNonNull(useSsl);
 | ||
|  |     this.systemAuthentication = Objects.requireNonNull(systemAuthentication);
 | ||
|  |   }
 | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * Call the Auth Service to generate a session token for a particular user with a unique actor id, or throws an exception if generation fails.
 | ||
|  |    *
 | ||
|  |    * Notice that the "userId" parameter should NOT be of type "urn", but rather the unique id of an Actor of type
 | ||
|  |    * USER.
 | ||
|  |    */
 | ||
|  |   @Nonnull
 | ||
|  |   public String generateSessionTokenForUser(@Nonnull final String userId) {
 | ||
|  |     Objects.requireNonNull(userId, "userId must not be null");
 | ||
|  |     CloseableHttpClient httpClient = HttpClients.createDefault();
 | ||
|  | 
 | ||
|  |     try {
 | ||
|  | 
 | ||
|  |       final String protocol = this.metadataServiceUseSsl ? "https" : "http";
 | ||
|  |       final HttpPost request = new HttpPost(String.format("%s://%s:%s/%s", protocol, this.metadataServiceHost, this.metadataServicePort, GENERATE_SESSION_TOKEN_ENDPOINT));
 | ||
|  | 
 | ||
|  |       // Build JSON request to generate a token on behalf of a user.
 | ||
|  |       String json = String.format("{ \"%s\":\"%s\" }", USER_ID_FIELD, userId);
 | ||
|  |       request.setEntity(new StringEntity(json));
 | ||
|  | 
 | ||
|  |       // Add authorization header with DataHub frontend system id and secret.
 | ||
|  |       request.addHeader(Http.HeaderNames.AUTHORIZATION, this.systemAuthentication.getCredentials());
 | ||
|  | 
 | ||
|  |       CloseableHttpResponse response = httpClient.execute(request);
 | ||
|  |       final HttpEntity entity = response.getEntity();
 | ||
|  |       if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK && entity != null) {
 | ||
|  |         // Successfully generated a token for the User
 | ||
|  |         final String jsonStr = EntityUtils.toString(entity);
 | ||
|  |         return getAccessTokenFromJson(jsonStr);
 | ||
|  |       } else {
 | ||
|  |         throw new RuntimeException(
 | ||
|  |             String.format("Bad response from the Metadata Service: %s %s",
 | ||
|  |                 response.getStatusLine().toString(), response.getEntity().toString()));
 | ||
|  |       }
 | ||
|  |     } catch (Exception e) {
 | ||
|  |       throw new RuntimeException("Failed to generate session token for user", e);
 | ||
|  |     } finally {
 | ||
|  |       try {
 | ||
|  |         httpClient.close();
 | ||
|  |       } catch (Exception e) {
 | ||
|  |         log.warn("Failed to close http client", e);
 | ||
|  |       }
 | ||
|  |     }
 | ||
|  |   }
 | ||
|  | 
 | ||
|  |   private String getAccessTokenFromJson(final String jsonStr) {
 | ||
|  |     ObjectMapper mapper = new ObjectMapper();
 | ||
|  |     try {
 | ||
|  |       return mapper.readTree(jsonStr).get(ACCESS_TOKEN_FIELD).asText();
 | ||
|  |     } catch (Exception e) {
 | ||
|  |       // Do not log the raw json in case it contains access token.
 | ||
|  |       throw new IllegalArgumentException("Failed to parse JSON received from the MetadataService!");
 | ||
|  |     }
 | ||
|  |   }
 | ||
|  | }
 |