JWT Token Creation In Java Using SAP Cloud Security

616 Views Asked by At

I am having trouble to generate JWT Access Token in Java SpringBoot Application using SAP Cloud SDK.

Below are the steps -

  1. Created xsuaa service instance with plan apiaccess in SAP Cloud Platform Cockpit with service key.

    xsuaa service instance

  2. The service key has clientid, clientsecret and url that will be used for generating access token.

  3. Tried to generate the access token in Postman. It is successful as shown below.

    Access token generation in Postman

  4. Switched to Java Application. The java app is a Spring-based project on SAP Cloud Platform.

  5. Below is the java code for access token generation -

    import java.net.URI; import java.net.URISyntaxException;
    
    
    import org.springframework.stereotype.Service;
    
    import com.sap.cloud.security.xsuaa.client.ClientCredentials;
    import com.sap.cloud.security.xsuaa.client.DefaultOAuth2TokenService;
    import com.sap.cloud.security.xsuaa.client.XsuaaDefaultEndpoints;
    import com.sap.cloud.security.xsuaa.tokenflows.TokenFlowException;
    import com.sap.cloud.security.xsuaa.tokenflows.XsuaaTokenFlows;
    
    import lombok.extern.slf4j.Slf4j;
    
    @Slf4j
    @Service
    public class UserManagement {
        private String authURL = "https://{subdomain}.authentication.eu10.hana.ondemand.com";
        private String clientID = "**";
        private String clientSecret = "***";
    
    
        public String generateJWTToken() {
    
            try {
    
                URI authUri = new URI(authURL);
    
                System.out.println(authURL);
                System.out.println(authUri);
                XsuaaTokenFlows tokenFlows = new XsuaaTokenFlows(new DefaultOAuth2TokenService(),
                        new XsuaaDefaultEndpoints(authUri.toString()), new ClientCredentials(clientID, clientSecret));
    
                System.out.println(tokenFlows.toString());
    
                String jwtToken = tokenFlows.clientCredentialsTokenFlow().execute().getAccessToken();
    
                return jwtToken;
            }catch (TokenFlowException e) {
                log.error("Token Flow Exception found ", e);
                throw new BusinessException(ExceptionEnum.TOKEN_FLOW_ERROR);
            } catch (URISyntaxException e) {
                log.error("URI Syntax Exception found ", e);
                throw new BusinessException(ExceptionEnum.URI_PARSE_ERROR);
            }
    
    }
    
  6. I run the application in eclipse and below is the error:

     https://{subdomain}.authentication.eu10.hana.ondemand.com
     https://{subdomain}.authentication.eu10.hana.ondemand.com
     com.sap.cloud.security.xsuaa.tokenflows.XsuaaTokenFlows@b3fea34
     2021-09-03 16:14:27.567 ERROR 15700 --- [nio-8081-exec-1]
     c.b.s.a.service.imp.UserManagement       : Token Flow Exception found 
    
     com.sap.cloud.security.xsuaa.tokenflows.TokenFlowException: Error
     requesting technical user token with grant_type 'client_credentials':
     Unexpected error retrieving JWT token:
     rb-app-lib-d.authentication.eu10.hana.ondemand.com     at
     com.sap.cloud.security.xsuaa.tokenflows.ClientCredentialsTokenFlow.requestTechnicalUserToken(ClientCredentialsTokenFlow.java:187)
        at
     com.sap.cloud.security.xsuaa.tokenflows.ClientCredentialsTokenFlow.execute(ClientCredentialsTokenFlow.java:139)
        at
     com.bosch.sbs.applibrary.service.imp.UserManagement.generateJWTToken(UserManagement.java:49)
        at
     com.bosch.sbs.applibrary.controller.UserController.testisds(UserController.java:69)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at
     sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at
     sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)     at
     org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
        at
     org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
        at
     org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
        at
     org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
        at
     org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
        at
     org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
        at
     org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060)
        at
     org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
        at
     org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
        at
     org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)     at
     org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)     at
     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
        at
     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at
     org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at
     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at
     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at
     com.sap.cloud.sdk.cloudplatform.servlet.RequestAccessorFilter.lambda$doFilter$1(RequestAccessorFilter.java:75)
        at
     com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.lambda$execute$0(AbstractThreadContextExecutor.java:317)
        at
     com.sap.cloud.sdk.cloudplatform.security.SecurityContextThreadContextDecorator.lambda$decorateCallable$2(SecurityContextThreadContextDecorator.java:51)
        at
     com.sap.cloud.sdk.cloudplatform.thread.ThreadContextCallable.call(ThreadContextCallable.java:225)
        at
     com.sap.cloud.sdk.cloudplatform.thread.AbstractThreadContextExecutor.execute(AbstractThreadContextExecutor.java:319)
        at
     com.sap.cloud.sdk.cloudplatform.servlet.RequestAccessorFilter.doFilter(RequestAccessorFilter.java:75)
        at
     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at
     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
        at
     org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
        at
     org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
        at
     org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
        at
     org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
        at
     org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
        at
     org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
        at
     org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
        at
     org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
        at
     org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
        at
     org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at
     org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
        at
     org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
        at
     org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
        at
     org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
        at
     org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
        at
     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at
     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at
     org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
        at
     org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at
     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at
     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at
     org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
        at
     org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at
     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at
     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at
     org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
        at
     org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at
     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at
     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at
     org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
        at
     org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
        at
     org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
        at
     org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
        at
     org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at
     org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
        at
     org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
        at
     org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
        at
     org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at
     org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)
        at
     org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)
        at
     org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at
     java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at
     java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at
     org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748) Caused by:
     com.sap.cloud.security.xsuaa.client.OAuth2ServiceException: Unexpected
     error retrieving JWT token:
     rb-app-lib-d.authentication.eu10.hana.ondemand.com     at
     com.sap.cloud.security.xsuaa.client.DefaultOAuth2TokenService.executeRequest(DefaultOAuth2TokenService.java:82)
        at
     com.sap.cloud.security.xsuaa.client.DefaultOAuth2TokenService.requestAccessToken(DefaultOAuth2TokenService.java:59)
        at
     com.sap.cloud.security.xsuaa.client.AbstractOAuth2TokenService.getAndCacheToken(AbstractOAuth2TokenService.java:299)
        at
     com.sap.cloud.security.xsuaa.client.AbstractOAuth2TokenService.getOrRequestAccessToken(AbstractOAuth2TokenService.java:257)
        at
     com.sap.cloud.security.xsuaa.client.AbstractOAuth2TokenService.getOAuth2TokenResponse(AbstractOAuth2TokenService.java:246)
        at
     com.sap.cloud.security.xsuaa.client.AbstractOAuth2TokenService.retrieveAccessTokenViaClientCredentialsGrant(AbstractOAuth2TokenService.java:106)
        at
     com.sap.cloud.security.xsuaa.tokenflows.ClientCredentialsTokenFlow.requestTechnicalUserToken(ClientCredentialsTokenFlow.java:181)
        ... 99 common frames omitted
    

I want to first try to generate the access token locally in Eclipse. I am sure that the authentication url, clientid and clientsecret values are correct.

I dont understand why in Postman, I am able to generate the access token by using the url, clientid and clientsecret directly, whereas in java it fails.

1

There are 1 best solutions below

0
Shreyasi Chakraborty On

The above mentioned process works fine if your application is not behind a proxy. I deployed this application to SAP Cloud and it works fine. The issue in local testing was proxy set by my Organisation. Hence I am closing this question. Thank you!