Access API Gateway application Identifier Claim set in IS service.

Hi Experts,

We need to access API Gateway application Identifier Claim set in REST Service on Integration server.

Reason:
We need to set some key/value pairs that will remain hidden from consumer but need to access those mapping in REST Service.

Scenario:
For example “LabelNumber” will be different for each consumer. Once request is authenticated in API Gateway, we need to pass LabelNumber to REST API for all the methods. But this number cannot be shared with consumer.

We are using API Portal and API Gateway advanced edition version 10.3.

Thanks,
Vineet Sharma.

Hi,
You can use the application rest service (<host:port>/rest/apigateway/applications/<<app_id>>) and then extract the identifiers field from the response.
Note: For the JWT claims, the value will be in JSON format you need to parse it and extract the actual value for a key.

Hi Srikar,

How do I get app_id @ runtime?
We don’t want to ask consumer to pass app_id with access token.

This(apigateway.applications:getApplication) runs properly if we run on browser using invoke or rest. But it fails everytime when we call it from flow service in IS.

Error:
Could not run ‘getApplication’
java.lang.RuntimeException: com.wm.data.ISMemDataImpl cannot be cast to com.wm.util.Values

Regards,
Vineet Sharma

Hi Srikar,

I was able to write below Java service to get all the claims from the messageContext.

First we need to add WmAPIGateway as dependency of our package to put application model classes in path for java service.

[size=9]import com.softwareag.pg.rest.RestMessageContext;
import com.softwareag.apigateway.api.model.application.Application;
import com.softwareag.apigateway.api.model.application.ApplicationIdentifier;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

    public static final void getClaims(IData pipeline) throws ServiceException {
	// pipeline
	IDataCursor pipelineCursor = pipeline.getCursor();
		Object	MessageContext = IDataUtil.get( pipelineCursor, "MessageContext" );
	pipelineCursor.destroy();		
	
	RestMessageContext synCtx = (RestMessageContext)MessageContext; 
	Application identifiedApp=(Application)synCtx.getProperty("gateway.identifiedApplication");
	ApplicationIdentifier appIdentifier=identifiedApp.getIdentifiers().get(0);
	List<ApplicationIdentifier.NamedPair> npList=appIdentifier.getNamedValues();
	
	// pipeline
	pipelineCursor = pipeline.getCursor();
	
	// Claims
	IData	Claims = IDataFactory.create();
	IDataCursor ClaimsCursor = Claims.getCursor();
	for (ApplicationIdentifier.NamedPair namedPair : npList) {
		String claimName=namedPair.getName();
		
		// Claims.JWT ClaimSet
		IData	ClaimSet = IDataFactory.create();
		IDataCursor ClaimSetCursor = ClaimSet.getCursor();
		List<String> values=namedPair.getValues();
		Map<String,String> valueMap=JsonToMap(values.get(0));
		Object keys[]=valueMap.keySet().toArray();
		for (Object key : keys) {
			IDataUtil.put( ClaimSetCursor, (String)key, valueMap.get((String)key));
		}
		ClaimSetCursor.destroy();
		IDataUtil.put( ClaimsCursor, claimName, ClaimSet );
		ClaimsCursor.destroy();
	}
	
	IDataUtil.put( pipelineCursor, "Claims", Claims );
	pipelineCursor.destroy();	
}

    public static Map<String,String> JsonToMap(String JSON){
		ObjectMapper mapper = new ObjectMapper();
		Map<String, String> namedPair=null;
                try {
                     namedPair = mapper.readValue(JSON, new TypeReference<Map<String, String>>() {});
                } catch (Exception e) {
                     e.printStackTrace();
                }
		return namedPair;
}[/size]

Please let me know if there is any other SAG recommended way to do it.

Regards,
Vineet Sharma.

Hi Vineet,
No its good, i would suggest few small things.

  1. To check for JWT Claims (appIdentifier.getKey() == “jwtClaims”) so that even if other identifiers are also available it shouldn’t be a problem.
  2. You are destroying the ClaimsCursor.destroy(); earlier inside the loop.
    Also I assume defining one claimSet would solve your usecase. So I would suggest including the claimSet in the pipeline directly. So that even if by accident an application has a different claimSet name it shouldn’t cause a issue.