
com.sap.cloud.sdk.cloudplatform.connectivity.GetAuthHeadersCommand Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of connectivity-scp-neo Show documentation
Show all versions of connectivity-scp-neo Show documentation
Implementation of the Cloud platform abstraction for general-purpose connectivity
on the SAP Cloud Platform (Cloud Foundry).
The newest version!
/*
* Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved.
*/
package com.sap.cloud.sdk.cloudplatform.connectivity;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationOAuthTokenException;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.cloudplatform.servlet.Property;
import com.sap.cloud.sdk.cloudplatform.servlet.RequestContext;
import com.sap.cloud.sdk.cloudplatform.servlet.RequestContextAccessor;
import com.sap.cloud.sdk.cloudplatform.servlet.RequestContextExecutor;
import com.sap.cloud.sdk.cloudplatform.servlet.RequestContextServletFilter;
import com.sap.cloud.sdk.cloudplatform.servlet.exception.RequestContextPropertyException;
import com.sap.cloud.sdk.frameworks.hystrix.Command;
import com.sap.cloud.sdk.frameworks.hystrix.HystrixUtil;
import com.sap.core.connectivity.api.authentication.AuthenticationHeader;
import com.sap.core.connectivity.api.authentication.AuthenticationHeaderProvider;
import com.sap.core.connectivity.api.configuration.DestinationConfiguration;
import lombok.Data;
class GetAuthHeadersCommand extends Command>
{
private static final Logger logger = CloudLoggerFactory.getLogger(GetAuthHeadersCommand.class);
@Data
private static class CommandSetterBuilder
{
private final Class extends Command>> commandClass;
private String getCommandKey( final String destinationName, final URI requestUri )
{
final String commandKey =
HystrixUtil.getTenantIsolatedKey(commandClass) + HystrixUtil.getDelimiter() + destinationName;
if( logger.isDebugEnabled() ) {
logger.debug(
"Constructed command key: '"
+ commandKey
+ "'. Destination: '"
+ destinationName
+ "', request URI: '"
+ requestUri
+ "').");
}
return commandKey;
}
HystrixCommand.Setter build( final String destinationName, final URI requestUri )
{
final String groupKey = HystrixUtil.getGlobalKey(commandClass);
final String commandKey = getCommandKey(destinationName, requestUri);
final HystrixCommandProperties.Setter commandProperties =
HystrixCommandProperties
.Setter()
.withExecutionTimeoutInMilliseconds(6000)
.withCircuitBreakerEnabled(true)
.withCircuitBreakerSleepWindowInMilliseconds(6000)
.withFallbackEnabled(false);
return HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
.andThreadPoolPropertiesDefaults(
HystrixThreadPoolProperties
.Setter()
.withCoreSize(10)
.withQueueSizeRejectionThreshold(100)
.withMaxQueueSize(100))
.andCommandPropertiesDefaults(commandProperties);
}
}
private static final CommandSetterBuilder setterBuilder = new CommandSetterBuilder(GetAuthHeadersCommand.class);
private final ScpNeoDestination destination;
@Nullable
private final URI requestUri;
GetAuthHeadersCommand( final ScpNeoDestination destination, @Nullable final URI requestUri )
{
super(setterBuilder.build(destination.getName(), requestUri));
this.destination = destination;
this.requestUri = requestUri;
}
@Override
protected List run()
throws DestinationAccessException
{
@Nullable
final DestinationConfiguration destinationConfiguration = destination.getDestinationConfiguration();
if( destinationConfiguration == null ) {
if( logger.isDebugEnabled() ) {
logger.debug("Skipping fetching of authentication headers: DestinationConfiguration is null.");
}
return Collections.emptyList();
}
return getAuthenticationHeaders(destinationConfiguration);
}
private AuthenticationHeaderProvider getAuthenticationHeaderProvider()
throws DestinationAccessException
{
final Optional requestContext = RequestContextAccessor.getCurrentRequestContext();
if( !requestContext.isPresent() ) {
throw new DestinationAccessException(
"Failed to get "
+ AuthenticationHeaderProvider.class.getSimpleName()
+ ": no "
+ RequestContext.class.getSimpleName()
+ " available."
+ " Have you correctly configured a "
+ RequestContextServletFilter.class.getSimpleName()
+ " or have you wrapped your logic in a "
+ RequestContextExecutor.class.getSimpleName()
+ " when executing background tasks that are not triggered by a request?");
}
try {
final Optional> property =
requestContext.get().getProperty(
ScpNeoDestinationsRequestContextListener.PROPERTY_AUTHENTICATION_HEADER_PROVIDER);
if( !property.isPresent() ) {
throw new DestinationAccessException(
"Failed to get "
+ AuthenticationHeaderProvider.class.getSimpleName()
+ ": "
+ RequestContext.class.getSimpleName()
+ " property '"
+ ScpNeoDestinationsRequestContextListener.PROPERTY_AUTHENTICATION_HEADER_PROVIDER
+ "' is not present. "
+ "Please ensure that "
+ ScpNeoDestinationsRequestContextListener.class.getSimpleName()
+ " is available on the class path.");
}
@Nullable
final Exception exception = property.get().getException();
if( exception != null ) {
throw new DestinationAccessException(
"Failed to get " + AuthenticationHeaderProvider.class.getSimpleName() + ".",
exception);
}
return (AuthenticationHeaderProvider) property.get().getValue();
}
catch( final RequestContextPropertyException e ) {
throw new DestinationAccessException(
"Failed to get "
+ AuthenticationHeaderProvider.class.getSimpleName()
+ ": failed to get "
+ RequestContext.class.getSimpleName()
+ " property.",
e);
}
}
private List getAuthenticationHeaders( final DestinationConfiguration destinationConfiguration )
throws DestinationAccessException
{
final AuthenticationHeaderProvider authenticationHeaderProvider = getAuthenticationHeaderProvider();
try {
final List authenticationHeaders = new ArrayList<>();
switch( destination.getAuthenticationType() ) {
case PRINCIPAL_PROPAGATION: {
authenticationHeaders
.add(transformHeader(authenticationHeaderProvider.getPrincipalPropagationHeader()));
break;
}
case OAUTH2_CLIENT_CREDENTIALS: {
authenticationHeaders.add(
transformHeader(
authenticationHeaderProvider.getOAuth2ClientCredentialsHeader(destinationConfiguration)));
break;
}
case OAUTH2_SAML_BEARER_ASSERTION: {
authenticationHeaders.addAll(
transformHeaders(
authenticationHeaderProvider
.getOAuth2SAMLBearerAssertionHeaders(destinationConfiguration)));
break;
}
case APP_TO_APP_SSO: {
authenticationHeaders.add(
transformHeader(
authenticationHeaderProvider.getApptoAppSSOHeader(
(requestUri != null ? requestUri : destination.getUri()).toString(),
destinationConfiguration)));
break;
}
case SAP_ASSERTION_SSO: {
authenticationHeaders.add(
transformHeader(authenticationHeaderProvider.getSAPAssertionHeader(destinationConfiguration)));
break;
}
case NO_AUTHENTICATION:
case BASIC_AUTHENTICATION:
case CLIENT_CERTIFICATE_AUTHENTICATION:
case INTERNAL_SYSTEM_AUTHENTICATION:
default:
// authentication headers must not be retrieved via the authentication header API
break;
}
return authenticationHeaders;
}
catch( final IllegalArgumentException | IllegalStateException e ) {
if( e.getMessage() != null && e.getMessage().contains("OAuthTokenGenerationException") ) {
throw new DestinationOAuthTokenException(destination.getName(), e);
}
throw new DestinationAccessException(e);
}
}
private Header transformHeader( final AuthenticationHeader authenticationHeader )
{
return new Header(authenticationHeader.getName(), authenticationHeader.getValue());
}
private Collection transformHeaders( final Iterable authenticationHeaders )
{
final List headers = new ArrayList<>();
for( final AuthenticationHeader authenticationHeader : authenticationHeaders ) {
headers.add(transformHeader(authenticationHeader));
}
return headers;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy