Wso2ESB: Call Response API through an Access Policy from a Client Issuing a CORS Problem

I encountered a Cross origin problem when trying to call the ESB Rest API, which has a rights policy. Please find below client call, ESB API and Handler.

  • Ajax call:

 $.ajax({
	        beforeSend: function(xhr) {
	        xhr.setRequestHeader('Authorization', 'Bearer 5d8ce0224d82cca7fb55fdcf4015b67');
},
	            	    withCredentials: true,
	            		dataType: "json",
	            		type: 'GET',
	            		url: relativeURL+"/test,
	            	    },
	            	    success: function(json) 
	            	    {}});
Run codeHide result
  1. ESB API Configuration

<api xmlns="http://ws.apache.org/ns/synapse" name="CustomerApi"     context="/CustomerApi">
      <resource methods="POST GET OPTIONS DELETE PUT">
      <inSequence>
         <log level="custom">
            <property name="Message Flow" value="Customer Search API - IN">   </property>
            <property name="HTTP_METHOD IS###########" expression="$axis2:HTTP_METHOD"></property>
            <property name="ip address" expression="get-property('axis2','REMOTE_ADDR')"></property>
         </log>
         <property name="Authorization" expression="get-property('transport','Authorization')"></property>
         <property name="Access-Control-Allow-Credentials" value="true" scope="transport"></property>
         <property name="Access-Control-Allow-Headers" value="authorization,Access-Control-Allow-Origin,Content-Type,origin,accept,X-Requested-With" scope="transport"></property>
         <property name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" scope="transport"></property>
         <property name="Access-Control-Allow-Origin" value="*" scope="transport"></property>
         <property name="xacml_use_rest" value="true" scope="axis2" type="STRING"></property>
         <property name="xacml_resource_prefix" value="/api/customers" scope="axis2"></property>
         <property name="xacml_resource_prefix_only" value="true" scope="axis2"></property>
         <property name="TIME_IN" expression="get-property('SYSTEM_TIME')" scope="default" type="LONG"></property>
         <log level="custom">
            <property name="Authorization.........." expression="get-property('transport','Authorization')"></property>
         </log>
         <entitlementService remoteServiceUrl="https://localhost:9444/services" remoteServiceUserName="admin" remoteServicePassword="enc:kuv2MubUUveMyv6GeHrXr9il59ajJIqUI4eoYHcgGKf/BBFOWn96NTjJQI+wYbWjKW6r79S7L7ZzgYeWx7DlGbff5X3pBN2Gh9yV0BHP1E93QtFqR7uTWi141Tr7V7ZwScwNqJbiNoV+vyLbsqKJE7T3nP8Ih9Y6omygbcLcHzg=" callbackClass="org.wso2.carbon.identity.entitlement.mediator.callback.UTEntitlementCallbackHandler" client="basicAuth">
            <onReject>
               <log level="custom">
                  <property name="Message Flow" value="REJECTED@ Dobbies"></property>
               </log>
               <property name="HTTP_SC" value="401" scope="axis2" type="STRING"></property>
               <payloadFactory media-type="xml">
                  <format>
                     <oatherizationresponse xmlns="">Not Authorized </oatherizationresponse>
                  </format>
                  <args></args>
               </payloadFactory>
               <respond></respond>
            </onReject>
            <onAccept>
               <log level="custom">
                  <property name="Message Flow" value="ACCEPTED@ Dobbies"></property>
               </log>
               <property name="Authorization" expression="fn:concat('Basic ', base64Encode('test:test'))" scope="transport"></property>
               <send>
                  <endpoint>
                     <address uri="/api/customers/"></address>
                  </endpoint>
               </send>
               <property name="TIME_OUT" expression="get-property('SYSTEM_TIME')" scope="default" type="LONG"></property>
               <script language="js">var time1 = mc.getProperty("TIME_IN");var time2 = mc.getProperty("TIME_OUT");var timeTaken = time2 - time1;mc.setProperty("RESPONSE_TIME", timeTaken);</script>
               <log level="custom">
                  <property name="Time Duration in ms:" expression="get-property('RESPONSE_TIME') "></property>
               </log>
            </onAccept>
            <obligations></obligations>
            <advice></advice>
         </entitlementService>
      </inSequence>
      <outSequence>
         <send></send>
      </outSequence>
       </resource>
      <handlers>
         <handler class="org.wso2.handler.SimpleOauthHandlerNew">
      </handler>
      </handlers
      </api>
Run codeHide result
  1. SimpleOauthHandlerNew:

package org.wso2.handler;
    import java.util.Map;

    import org.apache.axis2.client.Options;
    import org.apache.axis2.client.ServiceClient;
    import org.apache.axis2.context.ConfigurationContext;
    import org.apache.axis2.context.ConfigurationContextFactory;
    import org.apache.axis2.transport.http.HTTPConstants;
    import org.apache.axis2.transport.http.HttpTransportProperties;
    import org.apache.http.HttpHeaders;
    import org.apache.synapse.ManagedLifecycle;
    import org.apache.synapse.MessageContext;
    import org.apache.synapse.core.SynapseEnvironment;
    import org.apache.synapse.core.axis2.Axis2MessageContext;
     import org.apache.synapse.rest.AbstractHandler;
    import org.wso2.carbon.identity.oauth2.stub.OAuth2ServiceStub;
    import    org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
    import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO;
    import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO_OAuth2AccessToken;
    import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationResponseDTO;
 
    public class SimpleOauthHandlerNew extends AbstractHandler implements  ManagedLifecycle {
 
    private String securityHeader = HttpHeaders.AUTHORIZATION;
    private String consumerKeyHeaderSegment = "Bearer";
    private String oauthHeaderSplitter = ",";
    private String consumerKeySegmentDelimiter = " ";
    private String oauth2TokenValidationService = "oauth2TokenValidationService";
    private String identityServerUserName = "identityServerUserName";
    private String identityServerPw = "identityServerPw";
    private String oAuth2Service = "oauth2Service";
 
    @Override
    public boolean handleRequest(MessageContext messageContext) {
        try{
            ConfigurationContext configCtx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
            //Read parameters from axis2.xml
            String identityServerUrl = messageContext.getConfiguration().getAxisConfiguration().getParameter(oauth2TokenValidationService).getValue().toString();
            String username = messageContext.getConfiguration().getAxisConfiguration().getParameter(identityServerUserName).getValue().toString();
            String password = messageContext.getConfiguration().getAxisConfiguration().getParameter(identityServerPw).getValue().toString();
 
             OAuth2TokenValidationServiceStub stub = new OAuth2TokenValidationServiceStub(configCtx,identityServerUrl);
             
             String oauth2ServiceUrl = messageContext.getConfiguration().getAxisConfiguration().getParameter(oAuth2Service).getValue().toString();
             OAuth2ServiceStub oAuth2ServiceStub = new OAuth2ServiceStub(configCtx,oauth2ServiceUrl);
             
             
             ServiceClient client = stub._getServiceClient();
             Options options = client.getOptions();
             HttpTransportProperties.Authenticator authenticator = new HttpTransportProperties.Authenticator();
             authenticator.setUsername(username);
             authenticator.setPassword(password);
             authenticator.setPreemptiveAuthentication(true);
 
             options.setProperty(HTTPConstants.AUTHENTICATE, authenticator);
             client.setOptions(options);
             OAuth2TokenValidationRequestDTO dto = new OAuth2TokenValidationRequestDTO();
           // dto.set("bearer");
             Map headers = (Map) ((Axis2MessageContext) messageContext).getAxis2MessageContext().
                     getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
            String apiKey = null;
            if (headers != null) {
                apiKey = extractCustomerKeyFromAuthHeader(headers);
            }
            OAuth2TokenValidationRequestDTO_OAuth2AccessToken accessToken = new OAuth2TokenValidationRequestDTO_OAuth2AccessToken();
            accessToken.setTokenType("bearer");
            accessToken.setIdentifier(apiKey);
            dto.setAccessToken(accessToken);
            //validate passed apiKey(token)
            if (stub.validate(dto).getValid()) {
                String user = stub.validate(dto).getAuthorizedUser();
                System.out.println(">>>>>>>>>"+user);
                user = user.substring(0, user.indexOf('@'));
                System.out.println(">>>>>>>>>"+user);
                org.apache.axis2.context.MessageContext msgContext;
                Axis2MessageContext axis2Msgcontext = null;
                axis2Msgcontext = (Axis2MessageContext) messageContext;
                msgContext = axis2Msgcontext.getAxis2MessageContext();
                msgContext.setProperty("username", user);
                return true;
            }else{
                return false;
            }
           }catch(Exception e){
            e.printStackTrace();
            return false;
           }
          }
 
       public String extractCustomerKeyFromAuthHeader(Map headersMap) {
 
        String authHeader = (String) headersMap.get(securityHeader);
        if (authHeader == null) {
            return null;
        }
 
        if (authHeader.startsWith("OAuth ") || authHeader.startsWith("oauth "))       {
            authHeader = authHeader.substring(authHeader.indexOf("o"));
        }
 
        String[] headers = authHeader.split(oauthHeaderSplitter);
        if (headers != null) {
            for (int i = 0; i < headers.length; i++) {
                String[] elements =   headers[i].split(consumerKeySegmentDelimiter);
                if (elements != null && elements.length > 1) {
                    int j = 0;
                    boolean isConsumerKeyHeaderAvailable = false;
                    for (String element : elements) {
                        if (!"".equals(element.trim())) {
                            if (consumerKeyHeaderSegment.equals(elements[j].trim())) {
                                isConsumerKeyHeaderAvailable = true;
                            } else if (isConsumerKeyHeaderAvailable) {
                                return removeLeadingAndTrailing(elements[j].trim());
                            }
                        }
                        j++;
                    }
                }
            }
        }
        return null;
        }
 
       private String removeLeadingAndTrailing(String base) {
        String result = base;
 
        if (base.startsWith("\"") || base.endsWith("\"")) {
            result = base.replace("\"", "");
        }
        return result.trim();
       }
 
     @Override
     public boolean handleResponse(MessageContext messageContext) {
        return true;
     }
 
     @Override
     public void init(SynapseEnvironment synapseEnvironment) {
        
     }
 
     @Override
     public void destroy() {
        
     }
 }
Run codeHide result

In the browser I get

XMLHttpRequest cannot load / CustomerApi? limit = 10 & offset = 0. The requested resource does not have an Access-Control-Allow-Origin header. Origin ' http://172.250.46.250:8095 ', therefore, is not allowed.

Please provide me a solution for calling a Rest endpoint from a client. Thanks in advance.

+4
source share
1 answer

, , , , .

CORS - API WSO2 API Manager CORS. https://docs.wso2.com/display/AM200/Enabling+CORS+for+APIs

WSO2 EI CORS API - HTTP- .

:

<header description="CORS" name="Access-Control-Allow-Origin" scope="transport" value="*"/>
+1

All Articles