0

I'd like to send a custom OData request to an on-premise SAP ABAP system, using the SAP CloudSDK 3.20.0. "Custom" meaning I cannot use virtual data models but assemble the request URL "by hand" and treat the response on my own, like regular REST requests.

My application runs with Java and Spring Boot. The intended request will take a while to complete and thus is sent from an asynchronous thread.

I have set up a cloud connector and could prove that the code and configuration are working fine with several Destinations that all use Basic Authentication. Now, attempting to use Principal Propagation for the first time, the code fails with an exception while trying to get an HTTP client:

try {
    Destination destination = DestinationAccessor.getDestination(destinationName);
    HttpDestination httpDestination = destination.asHttp().decorate(DefaultErpHttpDestination::new);
    // this fails:
    HttpClient httpClient = HttpClientAccessor.getHttpClient(httpDestination);
    // ...
} catch (Exception exception) {
    // receives 
    // DestinationAccessException: "Failed to get on-premise proxy headers."
    //     PrincipalAccessException: "Could not read a principal from neither
    //         a given JWT nor a given Basic Authentication header."
    // full stack trace below
}

My assumption is that I am doing something wrong with the asynchronous thread this is running in, that I am not passing on context completely or in the right way for the CloudSDK to propagate the principal.

The one thing I am doing is that I use AuthTokenAccessor.getCurrentToken() to retrieve the security token in the original thread and AuthTokenAccessor.executeWithAuthToken(authToken, command::run) to propagate the token to the thread started asynchronously from there.

Unfortunately, asynchronous threads with the CloudSDK are a pretty blank space, and I couldn't find any docu or tutorial that explains what exactly is needed here.

Stack trace

com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException: Failed to get on-premise proxy headers.
    at com.sap.cloud.sdk.cloudplatform.connectivity.ConnectivityService.getHeadersForOnPremiseSystem(ConnectivityService.java:62)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfHttpDestinationPropertyFactory.getOnPremiseProxyHeaders(ScpCfHttpDestinationPropertyFactory.java:673)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfHttpDestinationPropertyFactory.getHeadersFromDestination(ScpCfHttpDestinationPropertyFactory.java:591)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfHttpDestination.<init>(ScpCfHttpDestination.java:173)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfHttpDestination.<init>(ScpCfHttpDestination.java:79)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestination.asHttp(ScpCfDestination.java:49)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientFactory.getHttpDestination(DefaultHttpClientFactory.java:56)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientFactory.getHttpDestinationProperties(DefaultHttpClientFactory.java:44)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientFactory.getHttpClient(DefaultHttpClientFactory.java:32)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientFactory$$FastClassBySpringCGLIB$$87b87cd0.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientFactory$$EnhancerBySpringCGLIB$$8d195096.getHttpClient(<generated>)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientRetryExecutor.getHttpClient(DefaultHttpClientRetryExecutor.java:57)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientRetryExecutor.executeAndGetResponse(DefaultHttpClientRetryExecutor.java:49)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientRetryExecutor.executeWithRetry(DefaultHttpClientRetryExecutor.java:38)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientRetryExecutor$$FastClassBySpringCGLIB$$aa3836e1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.retry.interceptor.RetryOperationsInterceptor$1.doWithRetry(RetryOperationsInterceptor.java:91)
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287)
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:164)
    at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:118)
    at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:153)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultHttpClientRetryExecutor$$EnhancerBySpringCGLIB$$4196dda3.executeWithRetry(<generated>)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultRequestExecutor.executeGetRequestAndReturnHttpResponse(DefaultRequestExecutor.java:66)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultRequestExecutor.executeGetRequest(DefaultRequestExecutor.java:48)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultRequestExecutor$$FastClassBySpringCGLIB$$209b987b.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at com.sap.grc.automatedprocedures.api.odataadapter.common.http.DefaultRequestExecutor$$EnhancerBySpringCGLIB$$fdefc677.executeGetRequest(<generated>)
    at com.sap.grc.automatedprocedures.api.odataadapter.metadataadapters.DefaultOdataResultMetadataReader.readMetadata(DefaultOdataResultMetadataReader.java:32)
    at com.sap.grc.automatedprocedures.api.odataadapter.metadataadapters.DefaultOdataResultMetadataReader$$FastClassBySpringCGLIB$$7f270a2b.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at com.sap.grc.automatedprocedures.api.odataadapter.metadataadapters.DefaultOdataResultMetadataReader$$EnhancerBySpringCGLIB$$2aaea987.readMetadata(<generated>)
    at com.sap.grc.automatedprocedures.api.odataadapter.metadataadapters.OdataResultMetadataAdapter.enrichMetadata(OdataResultMetadataAdapter.java:53)
    at com.sap.grc.automatedprocedures.api.odataadapter.metadataadapters.OdataResultMetadataAdapter$$FastClassBySpringCGLIB$$7e0d7c0e.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at com.sap.grc.automatedprocedures.api.odataadapter.metadataadapters.OdataResultMetadataAdapter$$EnhancerBySpringCGLIB$$b15ac510.enrichMetadata(<generated>)
    at com.sap.grc.automatedprocedures.businesslogic.core.automatedprocedure.AutomatedProcedureMetadataRequestorTransaction.requestAndSaveMetadata(AutomatedProcedureMetadataRequestorTransaction.java:62)
    at com.sap.grc.automatedprocedures.businesslogic.core.automatedprocedure.AutomatedProcedureMetadataRequestorTransaction$$FastClassBySpringCGLIB$$319e3277.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at com.sap.grc.automatedprocedures.businesslogic.core.automatedprocedure.AutomatedProcedureMetadataRequestorTransaction$$EnhancerBySpringCGLIB$$d02aa2a4.requestAndSaveMetadata(<generated>)
    at com.sap.grc.automatedprocedures.businesslogic.core.automatedprocedure.DefaultAutomatedProcedureMetadataRequestor.requestAndSaveMetadata(DefaultAutomatedProcedureMetadataRequestor.java:35)
    at com.sap.grc.automatedprocedures.businesslogic.core.automatedprocedure.DefaultAutomatedProcedureMetadataRequestor$$FastClassBySpringCGLIB$$7ff09138.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at com.sap.cloud.sdk.cloudplatform.security.AuthTokenAccessor.lambda$executeWithAuthToken$3(AuthTokenAccessor.java:206)
    at com.sap.cloud.sdk.cloudplatform.thread.ThreadContextCallable.call(ThreadContextCallable.java:247)
    at com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.execute(AbstractThreadContextExecutor.java:293)
    at com.sap.cloud.sdk.cloudplatform.security.AuthTokenAccessor.executeWithAuthToken(AuthTokenAccessor.java:188)
    at com.sap.cloud.sdk.cloudplatform.security.AuthTokenAccessor.executeWithAuthToken(AuthTokenAccessor.java:205)
    at com.sap.grc.automatedprocedures.configuration.asynchronouslythreads.RequestContextExecutorConfiguration$WrappedExecutor.lambda$execute$0(RequestContextExecutorConfiguration.java:58)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:836)
Caused by: com.sap.cloud.sdk.cloudplatform.resilience.ResilienceRuntimeException: com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextExecutionException: com.sap.cloud.sdk.cloudplatform.security.exception.TokenRequestFailedException: Failed to determine cache key.
    at com.sap.cloud.sdk.frameworks.resilience4j.Resilience4jDecorationStrategy.lambda$null$2(Resilience4jDecorationStrategy.java:181)
    at io.vavr.control.Try.onFailure(Try.java:659)
    at com.sap.cloud.sdk.frameworks.resilience4j.Resilience4jDecorationStrategy.lambda$decorateCallable$3(Resilience4jDecorationStrategy.java:180)
    at com.sap.cloud.sdk.cloudplatform.resilience.ResilienceDecorationStrategy.executeCallable(ResilienceDecorationStrategy.java:210)
    at com.sap.cloud.sdk.cloudplatform.resilience.ResilienceDecorator.executeCallable(ResilienceDecorator.java:197)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ConnectivityService.getHeadersForOnPremiseSystem(ConnectivityService.java:50)
    ... 130 more
Caused by: com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextExecutionException: com.sap.cloud.sdk.cloudplatform.security.exception.TokenRequestFailedException: Failed to determine cache key.
    at com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.execute(AbstractThreadContextExecutor.java:299)
    at com.sap.cloud.sdk.frameworks.resilience4j.DefaultThreadContextProvider.lambda$decorateCallable$0(DefaultThreadContextProvider.java:26)
    ... 4 more
Caused by: com.sap.cloud.sdk.cloudplatform.security.exception.TokenRequestFailedException: Failed to determine cache key.
    at com.sap.cloud.sdk.cloudplatform.connectivity.XsuaaService.lambda$getUserTokenCacheKey$1(XsuaaService.java:106)
    at io.vavr.control.Try.getOrElseThrow(Try.java:748)
    at com.sap.cloud.sdk.cloudplatform.connectivity.XsuaaService.getUserTokenCacheKey(XsuaaService.java:106)
    at com.sap.cloud.sdk.cloudplatform.connectivity.XsuaaService.retrieveAccessTokenViaUserTokenGrant(XsuaaService.java:300)
    at com.sap.cloud.sdk.cloudplatform.connectivity.PrincipalPropagationStrategy.getHeadersWithRecommendedStrategy(PrincipalPropagationStrategy.java:202)
    at com.sap.cloud.sdk.cloudplatform.connectivity.ConnectivityService.lambda$getHeadersForOnPremiseSystem$0(ConnectivityService.java:51)
    at com.sap.cloud.sdk.frameworks.resilience4j.Resilience4jDecorationStrategy.lambda$decorateCallable$1(Resilience4jDecorationStrategy.java:160)
    at com.sap.cloud.sdk.cloudplatform.thread.ThreadContextCallable.call(ThreadContextCallable.java:247)
    at com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.execute(AbstractThreadContextExecutor.java:293)
    ... 5 more
Caused by: com.sap.cloud.sdk.cloudplatform.security.principal.exception.PrincipalAccessException: Could not read a principal from neither a given JWT nor a given Basic Authentication header.
    at com.sap.cloud.sdk.cloudplatform.security.principal.ScpCfPrincipalFacade.createFallbackException(ScpCfPrincipalFacade.java:92)
    at com.sap.cloud.sdk.cloudplatform.security.principal.ScpCfPrincipalFacade.tryGetCurrentPrincipal(ScpCfPrincipalFacade.java:87)
    at io.vavr.control.Try.flatMapTry(Try.java:490)
    at io.vavr.control.Try.flatMap(Try.java:472)
    at com.sap.cloud.sdk.cloudplatform.security.principal.PrincipalAccessor.tryGetCurrentPrincipal(PrincipalAccessor.java:112)
    at com.sap.cloud.sdk.cloudplatform.security.principal.PrincipalAccessor.getCurrentPrincipal(PrincipalAccessor.java:95)
    at com.sap.cloud.sdk.cloudplatform.cache.CacheKey.ofTenantAndPrincipalIsolation(CacheKey.java:184)
    at io.vavr.control.Try.of(Try.java:75)
    at com.sap.cloud.sdk.cloudplatform.connectivity.XsuaaService.getUserTokenCacheKey(XsuaaService.java:105)
    ... 11 more
    Suppressed: com.sap.cloud.sdk.cloudplatform.security.principal.exception.PrincipalAccessException: Could not read a principal from neither a given JWT nor a given Basic Authentication header.
        at com.sap.cloud.sdk.cloudplatform.security.principal.ScpCfPrincipalFacade.createFallbackException(ScpCfPrincipalFacade.java:92)
        at com.sap.cloud.sdk.cloudplatform.security.principal.ScpCfPrincipalFacade.tryGetCurrentPrincipal(ScpCfPrincipalFacade.java:87)
        at io.vavr.control.Try.flatMapTry(Try.java:490)
        at io.vavr.control.Try.flatMap(Try.java:472)
        at com.sap.cloud.sdk.cloudplatform.security.principal.PrincipalAccessor.tryGetCurrentPrincipal(PrincipalAccessor.java:112)
        at com.sap.cloud.sdk.cloudplatform.security.principal.PrincipalThreadContextListener.afterInitialize(PrincipalThreadContextListener.java:79)
        at com.sap.cloud.sdk.cloudplatform.thread.ThreadContextCallable.notifyAfterInitialize(ThreadContextCallable.java:144)
        at com.sap.cloud.sdk.cloudplatform.thread.ThreadContextCallable.call(ThreadContextCallable.java:245)
        at com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.execute(AbstractThreadContextExecutor.java:293)
        at com.sap.cloud.sdk.cloudplatform.security.AuthTokenAccessor.executeWithAuthToken(AuthTokenAccessor.java:188)
        at com.sap.cloud.sdk.cloudplatform.security.AuthTokenAccessor.executeWithAuthToken(AuthTokenAccessor.java:205)
        at com.sap.grc.automatedprocedures.configuration.asynchronouslythreads.RequestContextExecutorConfiguration$WrappedExecutor.lambda$execute$0(RequestContextExecutorConfiguration.java:58)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        ... 4 more
        Suppressed: com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextPropertyException: Property 'com.sap.cloud.sdk.cloudplatform.security.principal.PrincipalThreadContextListener:principal' does not exist.
            at com.sap.cloud.sdk.cloudplatform.thread.DefaultThreadContext.getProperty(DefaultThreadContext.java:45)
            at com.sap.cloud.sdk.cloudplatform.security.principal.DefaultPrincipalFacade.lambda$tryGetCurrentPrincipal$0(DefaultPrincipalFacade.java:28)
            at io.vavr.control.Try.flatMapTry(Try.java:490)
            at io.vavr.control.Try.flatMap(Try.java:472)
            at com.sap.cloud.sdk.cloudplatform.security.principal.DefaultPrincipalFacade.tryGetCurrentPrincipal(DefaultPrincipalFacade.java:28)
            at com.sap.cloud.sdk.cloudplatform.security.principal.ScpCfPrincipalFacade.tryGetCurrentPrincipal(ScpCfPrincipalFacade.java:81)
            ... 15 more
        Suppressed: com.sap.cloud.sdk.cloudplatform.security.principal.exception.PrincipalAccessException: There is no reader registered for grant type 'urn:ietf:params:oauth:grant-type:jwt-bearer'.
            at com.sap.cloud.sdk.cloudplatform.security.principal.AuthTokenPrincipalExtractor.lambda$getPrincipalId$c8b7f4af$1(AuthTokenPrincipalExtractor.java:97)
            at io.vavr.control.Try.of(Try.java:75)
            at com.sap.cloud.sdk.cloudplatform.security.principal.AuthTokenPrincipalExtractor.getPrincipalId(AuthTokenPrincipalExtractor.java:75)
            at com.sap.cloud.sdk.cloudplatform.security.principal.AuthTokenPrincipalExtractor.tryGetCurrentPrincipal(AuthTokenPrincipalExtractor.java:199)
            at io.vavr.control.Try.orElse(Try.java:726)
            at com.sap.cloud.sdk.cloudplatform.security.principal.ScpCfPrincipalFacade.tryGetCurrentPrincipal(ScpCfPrincipalFacade.java:83)
            ... 15 more
        Suppressed: com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextPropertyException: Property 'com.sap.cloud.sdk.cloudplatform.servlet.RequestThreadContextListener:request' does not exist.
            at com.sap.cloud.sdk.cloudplatform.thread.DefaultThreadContext.getProperty(DefaultThreadContext.java:45)
            at com.sap.cloud.sdk.cloudplatform.servlet.DefaultRequestFacade.lambda$tryGetCurrentRequest$0(DefaultRequestFacade.java:29)
            at io.vavr.control.Try.flatMapTry(Try.java:490)
            at io.vavr.control.Try.flatMap(Try.java:472)
            at com.sap.cloud.sdk.cloudplatform.servlet.DefaultRequestFacade.tryGetCurrentRequest(DefaultRequestFacade.java:29)
            at com.sap.cloud.sdk.cloudplatform.servlet.RequestAccessor.tryGetCurrentRequest(RequestAccessor.java:87)
            at com.sap.cloud.sdk.cloudplatform.security.DefaultBasicAuthenticationFacade.extractBasicCredentialsFromRequest(DefaultBasicAuthenticationFacade.java:72)
            at io.vavr.control.Try.orElse(Try.java:726)
            at com.sap.cloud.sdk.cloudplatform.security.DefaultBasicAuthenticationFacade.tryGetBasicCredentials(DefaultBasicAuthenticationFacade.java:55)
            at com.sap.cloud.sdk.cloudplatform.security.BasicAuthenticationAccessor.tryGetCurrentBasicCredentials(BasicAuthenticationAccessor.java:57)
            at com.sap.cloud.sdk.cloudplatform.security.principal.BasicCredentialsPrincipalExtractor.tryGetCurrentPrincipal(BasicCredentialsPrincipalExtractor.java:20)
            at io.vavr.control.Try.orElse(Try.java:726)
            at com.sap.cloud.sdk.cloudplatform.security.principal.ScpCfPrincipalFacade.tryGetCurrentPrincipal(ScpCfPrincipalFacade.java:85)
            ... 15 more
    Suppressed: com.sap.cloud.sdk.cloudplatform.security.principal.exception.PrincipalAccessException: There is no reader registered for grant type 'urn:ietf:params:oauth:grant-type:jwt-bearer'.
        at com.sap.cloud.sdk.cloudplatform.security.principal.AuthTokenPrincipalExtractor.lambda$getPrincipalId$c8b7f4af$1(AuthTokenPrincipalExtractor.java:97)
        at io.vavr.control.Try.of(Try.java:75)
        at com.sap.cloud.sdk.cloudplatform.security.principal.AuthTokenPrincipalExtractor.getPrincipalId(AuthTokenPrincipalExtractor.java:75)
        at com.sap.cloud.sdk.cloudplatform.security.principal.AuthTokenPrincipalExtractor.tryGetCurrentPrincipal(AuthTokenPrincipalExtractor.java:199)
        at io.vavr.control.Try.orElse(Try.java:726)
        at com.sap.cloud.sdk.cloudplatform.security.principal.ScpCfPrincipalFacade.tryGetCurrentPrincipal(ScpCfPrincipalFacade.java:83)
        ... 18 more
    Suppressed: com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextPropertyException: Property 'com.sap.cloud.sdk.cloudplatform.servlet.RequestThreadContextListener:request' does not exist.
        at com.sap.cloud.sdk.cloudplatform.thread.DefaultThreadContext.getProperty(DefaultThreadContext.java:45)
        at com.sap.cloud.sdk.cloudplatform.servlet.DefaultRequestFacade.lambda$tryGetCurrentRequest$0(DefaultRequestFacade.java:29)
        at io.vavr.control.Try.flatMapTry(Try.java:490)
        at io.vavr.control.Try.flatMap(Try.java:472)
        at com.sap.cloud.sdk.cloudplatform.servlet.DefaultRequestFacade.tryGetCurrentRequest(DefaultRequestFacade.java:29)
        at com.sap.cloud.sdk.cloudplatform.servlet.RequestAccessor.tryGetCurrentRequest(RequestAccessor.java:87)
        at com.sap.cloud.sdk.cloudplatform.security.DefaultBasicAuthenticationFacade.extractBasicCredentialsFromRequest(DefaultBasicAuthenticationFacade.java:72)
        at io.vavr.control.Try.orElse(Try.java:726)
        at com.sap.cloud.sdk.cloudplatform.security.DefaultBasicAuthenticationFacade.tryGetBasicCredentials(DefaultBasicAuthenticationFacade.java:55)
        at com.sap.cloud.sdk.cloudplatform.security.BasicAuthenticationAccessor.tryGetCurrentBasicCredentials(BasicAuthenticationAccessor.java:57)
        at com.sap.cloud.sdk.cloudplatform.security.principal.BasicCredentialsPrincipalExtractor.tryGetCurrentPrincipal(BasicCredentialsPrincipalExtractor.java:20)
        at io.vavr.control.Try.orElse(Try.java:726)
        at com.sap.cloud.sdk.cloudplatform.security.principal.ScpCfPrincipalFacade.tryGetCurrentPrincipal(ScpCfPrincipalFacade.java:85)
        ... 18 more
Florian
  • 4,821
  • 2
  • 19
  • 44

2 Answers2

1

regarding your sub-question on how to run operations asynchronously with the Cloud SDK: That is documented here.

AFAI can see you are doing it correctly. You could consider passing on the full thread context if you are unsure which information exactly will be needed, or if you want to avoid that information is extracted multiple times from an authorization token.

If you find the documentation to be missing essential information or have ideas on how it could be enhanced I recommend raising an issue or opening a pull request on the public GitHub.

MatKuhr
  • 505
  • 4
  • 13
0

Update:

This authentication type is supported as of Cloud SDK 3.26.0.


Initial answer:

From the exemplary exception stacktrace, I've noticed the grant type urn:ietf:params:oauth:grant-type:jwt-bearer could not be matched to the expected token types. This means, it is not really supported by SAP Cloud SDK. To be honest, I'm surprised to see that scenario.

Can you let us know, which SCP landscape you are working on? Is there a way for us to reproduce your setup? Where do you get the access token from? Are you using the approuter?


As a potential workaround, until investigation and fixing is completed, you could try the following:

PrincipalFacade principalFacade = PrincipalAccessor.getPrincipalFacade();

((ScpCfPrincipalFacade) principalFacade).setIdExtractorFunction(
  "urn:ietf:params:oauth:grant-type:jwt-bearer",
  jwt -> jwt.getClaim("user_name").asString());
MatKuhr
  • 505
  • 4
  • 13
Alexander Dümont
  • 903
  • 1
  • 5
  • 9
  • Finding out what's an intended scenario and what not is already one of the questions that are hard to answer from the available docu. :-( The app has a regular SAP Fiori UI with an AppRouter that retrieves the JWTs. The idea is now to let the app perform another request to another system in the user's name. The general idea didn't sound so outlandish. :-D – Florian Jul 07 '20 at 13:04
  • Due to the nature of ever changing SCP XSUAA and Approuter we sometimes face unfamiliar behavior. Of course our goal is to always keep Cloud SDK up-to-date, but some changes surprise us as well, even alternate behavior over different landscapes. If you are using Approuter + Cloud SDK on SCP CF with XSUAA, then you are doing everything right! Please let me know if the workaround above works for you. Then we'll update Cloud SDK ASAP. – Alexander Dümont Jul 07 '20 at 15:11
  • Update: We added a version 3.26.0 in which this authentication is supported. – Alexander Dümont Aug 17 '20 at 22:16