Skip to Content

Java to XSJS AppToAppSSO authentication

Hi Experts,

We are trying to read content from XSJS and print it in Java Servlet after SAML authentication and AppToAppSSO. The java application is deployed on SCP and IDP is configured as SF. SAML is configured in Hana. We are receiving unauthorized error in Servlet. Kindly find the Java code:

package com.poc;
import java.io.IOException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import javax.naming.Context;
import javax.naming.InitialContext;


import com.sap.core.connectivity.api.authentication.AuthenticationHeader;
import com.sap.core.connectivity.api.authentication.AuthenticationHeaderProvider;
import com.sap.core.connectivity.api.configuration.ConnectivityConfiguration;
import com.sap.core.connectivity.api.configuration.DestinationConfiguration;


public class CheckUser extends HttpServlet {
	private static final long serialVersionUID = 1L;


	private final Logger log = LoggerFactory.getLogger(this.getClass());


	public CheckUser() {
		super();
	}


	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub


		// String user = request.getRemoteUser();
		// response.getWriter().println("Hello:"+ user);


		// look up the connectivity authentication header provider resource
		// called "myAuthHeaderProvider"
		Context ctx;
		try {
			ctx = new InitialContext();
			ConnectivityConfiguration configuration = (ConnectivityConfiguration) ctx
					.lookup("java:comp/env/connectivityConfiguration");
			DestinationConfiguration destConfiguration = configuration.getConfiguration("xsjstest");
			log.info("dest config:" + destConfiguration);
			
			String url = destConfiguration.getProperty("URL") + "/sandbox/getUser.xsjs";
			log.info("url" + url);


			AuthenticationHeaderProvider authHeaderProvider = (AuthenticationHeaderProvider) ctx
					.lookup("java:comp/env/myAuthHeaderProvider");
			AuthenticationHeader appToAppSSOHeader = authHeaderProvider.getAppToAppSSOHeader(url);
			log.info("sso header:" + appToAppSSOHeader.getValue());
			
			HttpClient httpClient = HttpClients.createDefault();
			HttpGet req = new HttpGet(url);
			req.addHeader(appToAppSSOHeader.getName(), appToAppSSOHeader.getValue());


			HttpResponse res = httpClient.execute(req);
			String responseString = new BasicResponseHandler().handleResponse(res);
			response.getWriter().println(responseString);


		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


	}


	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}


}


Please find the destination :

Please find the logs of java application:

2019 03 13 06:20:25#+00#ERROR#org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/auth].[CheckUser]##anonymous#https-jsse-nio-8041-exec-6#na#a047f26b1#auth#web#a047f26b1#na#na#na#na#Servlet.service() for servlet [CheckUser] in context with path [/auth] threw exception org.apache.http.client.HttpResponseException: Unauthorized at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:67) at com.poc.CheckUser.doGet(CheckUser.java:80) at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at com.sap.core.communication.server.CertValidatorFilter.doFilter(CertValidatorFilter.java:331) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44) at com.sap.core.connectivity.jco.session.ext.RequestTracker.invoke(RequestTracker.java:55) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:610) at com.sap.cloud.runtime.impl.bridge.security.AbstractAuthenticator.invoke(AbstractAuthenticator.java:206) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650) at com.sap.core.tenant.valve.TenantValidationValve.invokeNextValve(TenantValidationValve.java:182) at com.sap.core.tenant.valve.TenantValidationValve.invoke(TenantValidationValve.java:97) at com.sap.js.statistics.tomcat.valve.RequestTracingValve.callNextValve(RequestTracingValve.java:113) at com.sap.js.statistics.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:59) at com.sap.core.js.monitoring.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:27) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) 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:836) 

Kindly let us know your insights on the same. I will be really thankful.

Best regards,

Ankit

capture.jpg (58.5 kB)
Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

2 Answers

  • Mar 13 at 01:30 PM

    Hi Ankit,

    Why are you using myAuthHeaderProvider as JNDI lookup?

    According to the docs you are supposed to use the default authentication lookup - not a custom one.

    You should define it on your web.xml like so:

    <resource-ref>
    	<res-ref-name>authenticationHeaderProvider</res-ref-name>
    	<res-type>com.sap.core.connectivity.api.authentication.AuthenticationHeaderProvider</res-type>
    </resource-ref>
    

    I also see that you've configured the destination with a wrong setting for saml_audience.

    Please read the blog with full step-by-step procedure on what you are trying here.

    Best regards,
    Ivan

    Add comment
    10|10000 characters needed characters exceeded

    • Hi Ivan,

      Thanks for your reply.

      We have already defined authentication in web.xml. I forgot to include in my question.

      Also, I hope we are using right value only for saml_audience. Kindly look at the saml service provider.

      Regards,

      Ankit

      capture.jpg (59.4 kB)
  • Mar 13 at 08:42 PM

    Hi Ankit,

    How is your web.xml?

    How do you initiate user authentication on SCP? Through your java application? Do you have an UI? Is this running on Neo or CF?

    I've found the following piece of code that should work for principal propagation:

    https://github.com/mmsaitharun/Workbox/blob/master/Workbox/WorkboxUtilities/src/main/java/com/workbox/util/component/RestUtil.java

    Apparently your java code should work. However, I wanted to see how authentication is taking place - as the original error you are facing is:

    HttpResponseException: Unauthorized

    Best regards,
    Ivan

    Add comment
    10|10000 characters needed characters exceeded

    • Hi Ankit,

      I don't really have any Successfactors instance to test this - but it should make no difference since we are just switching IdPs. So I believe I would be able to reproduce your error if you could share your project on github (at least a prototype where I could reproduce the error here).

      If not possible, than I would suggest you to debug your code and see what is really throwing the Unauthorized error.

      I would inspect the request headers being made by your code versus a request that works while calling the service from Postman.

      Best regards,
      Ivan