
com.sap.cloud.sdk.cloudplatform.security.AuthTokenRequest Maven / Gradle / Ivy
/*
* Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved.
*/
package com.sap.cloud.sdk.cloudplatform.security;
import java.io.IOException;
import java.net.URI;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.json.JsonSanitizer;
import com.sap.cloud.sdk.cloudplatform.CloudPlatform;
import com.sap.cloud.sdk.cloudplatform.CloudPlatformAccessor;
import com.sap.cloud.sdk.cloudplatform.ScpCfCloudPlatform;
import com.sap.cloud.sdk.cloudplatform.connectivity.HttpClientAccessor;
import com.sap.cloud.sdk.cloudplatform.connectivity.HttpEntityUtil;
import com.sap.cloud.sdk.cloudplatform.exception.ShouldNotHappenException;
import com.sap.cloud.sdk.cloudplatform.security.exception.TokenRequestFailedException;
import io.vavr.control.Try;
/**
* Class encapsulating the request to receive a JWT from an XSUAA service.
*/
class AuthTokenRequest
{
private final AuthTokenDecoder decoder;
/**
* Creates a request with the given decoder.
*
* @param decoder
* The decoder to decode the JWT from encoded String to decoded {@link AuthToken}. If null a new
* {@link AuthTokenDecoder} is used.
*/
AuthTokenRequest( @Nullable final AuthTokenDecoder decoder )
{
this.decoder = decoder == null ? new AuthTokenDecoder() : decoder;
}
/**
* Creates a request with a {@link AuthTokenDecoder} to validate the received JWT.
*/
AuthTokenRequest()
{
this(null);
}
/**
* Retrieves a validated authentication token from the bound XSUAA instance.
*
* @return An authentication token from the XSUAA instance.
*
* @throws TokenRequestFailedException
* If no XSUAA instance was bound or the communication with the service failed.
*/
@Nonnull
AuthToken getXsuaaServiceToken()
throws TokenRequestFailedException
{
// get XSUAA credentials from environment variables
final ScpCfCloudPlatform cloudPlatform = getCloudPlatform();
final JsonObject xsuaaCredentials = cloudPlatform.getXsuaaServiceCredentials();
return getXsuaaServiceToken(xsuaaCredentials);
}
private AuthToken getXsuaaServiceToken( final JsonObject xsuaaServiceCredentials )
throws TokenRequestFailedException
{
final String accessToken = Try.of(() -> {
final String clientId = xsuaaServiceCredentials.get("clientid").getAsString();
final String clientSecret = xsuaaServiceCredentials.get("clientsecret").getAsString();
final String xsuaaUrl = xsuaaServiceCredentials.get("url").getAsString();
final BasicCredentials clientCredentials = new BasicCredentials(clientId, clientSecret);
final URI requestUri = new URI(xsuaaUrl).resolve("/oauth/token?grant_type=client_credentials");
final HttpUriRequest request = new HttpPost(requestUri);
request.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString());
request.setHeader(
HttpHeaders.AUTHORIZATION,
"Basic " + BasicAuthHeaderEncoder.encodeUserPasswordBase64(clientCredentials));
final HttpResponse response = HttpClientAccessor.getHttpClient().execute(request);
return extractAccessToken(response);
}).getOrElseThrow(TokenRequestFailedException::new);
return decoder.decode(accessToken, null);
}
@Nullable
private String extractAccessToken( final HttpResponse response )
throws IOException
{
final String responseBody = HttpEntityUtil.getResponseBody(response);
final JsonObject responseBodyJson =
new JsonParser().parse(JsonSanitizer.sanitize(responseBody)).getAsJsonObject();
return responseBodyJson.get("access_token").getAsString();
}
private ScpCfCloudPlatform getCloudPlatform()
{
final CloudPlatform cloudPlatform = CloudPlatformAccessor.getCloudPlatform();
if( !(cloudPlatform instanceof ScpCfCloudPlatform) ) {
throw new ShouldNotHappenException(
"The current Cloud platform is not an instance of "
+ ScpCfCloudPlatform.class.getSimpleName()
+ ". Please make sure to specify a dependency to com.sap.cloud.s4hana.cloudplatform:core-scp-cf.");
}
return (ScpCfCloudPlatform) cloudPlatform;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy