cancel
Showing results for 
Search instead for 
Did you mean: 

Java to XSJS AppToAppSSO authentication

former_member313918
Participant
0 Kudos

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

Accepted Solutions (0)

Answers (2)

Answers (2)

Ivan-Mirisola
Product and Topic Expert
Product and Topic Expert

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

former_member313918
Participant
0 Kudos

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

Ivan-Mirisola
Product and Topic Expert
Product and Topic Expert
0 Kudos

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/workbo...

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

former_member313918
Participant
0 Kudos

Hi Ivan,

Sorry for delayed response.

I sincerely appreciate your time.

We have configured authentication in web.xml. Please find below :

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >


<web-app>
	<display-name>Archetype Created Web Application</display-name>
	<servlet>
		<servlet-name>CheckUser</servlet-name>
		<display-name>CheckUser</display-name>
		<description></description>
		<servlet-class>com.poc.CheckUser</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>CheckUser</servlet-name>
		<url-pattern>/CheckUser</url-pattern>
	</servlet-mapping>


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


	<resource-ref>
		<res-ref-name>connectivityConfiguration</res-ref-name>
		<res-type>com.sap.core.connectivity.api.configuration.ConnectivityConfiguration</res-type>
		<res-auth>Application</res-auth>		
	</resource-ref>


	<security-constraint>
		<web-resource-collection>
			<web-resource-name>User Name</web-resource-name>
			<url-pattern>/CheckUser</url-pattern>
		</web-resource-collection>
		<auth-constraint>
			<!-- Role Everyone will not be assignable -->
			<role-name>Everyone</role-name>
		</auth-constraint>
	</security-constraint>


	<security-constraint>
		<web-resource-collection>
			<web-resource-name>User Name</web-resource-name>
			<url-pattern>/index.jsp</url-pattern>
		</web-resource-collection>
	</security-constraint>




	<login-config>
		<auth-method>FORM</auth-method>
	</login-config>


	<security-role>
		<description>All SAP Cloud Platform users</description>
		<role-name>Everyone</role-name>
	</security-role>




</web-app>



Since SCP is using Successfactors IDP, CheckUser class asks credentials of SF. After providing credentials we receive error, where we were expecting xsjs result through principal propagation. SF user dynamically gets created in HANA and relevant roles get assigned to him but still no luck.

We don't have any UI as if now. Application is deployed in neo subaccount.

Regards,

Ankit

Ivan-Mirisola
Product and Topic Expert
Product and Topic Expert
0 Kudos

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