All docs This doc

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In most of the real-world use cases of REST, when a consumer attempts to access a privileged resource, credentials must be provided in an Authorization header or the consumer will be refused access. In WSO2 ESB, when we want to secure an API, we can simply make it available via HTTPS and let the security handlers validate the credentials. By default, the ESB does not include any REST Security Handlers, but the following example of a primitive security handler serves as a template that can can use be used to write your own security handler to secure an API in the ESB.

...

You can build the project (mvn clean install) for this handler by accessing its source here:

https://svngithub.wso2.orgcom/repos/wso2/carbon/platform/tags/turing-chunk07/products/esb/4.8.1product-esb/tree/v4.9.0/modules/samples/integration-scenarios/starbucks_sample/BasicAuth-handler_sample/BasicAuth-handler

Note

When building the sample using the source ensure you update pom.xml with the online repository. To do this, add the following section before <dependencies> tag in pom.xml:

Code Block
languagexml
<repositories>
	<repository>
	   <id>wso2-nexus</id>
	   <name>WSO2 internal Repository</name>
	   <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
	   <releases>
		  <enabled>true</enabled>
		  <updatePolicy>daily</updatePolicy>
		  <checksumPolicy>ignore</checksumPolicy>
	   </releases>
	 </repository>
	 <repository>
	   <id>wso2-maven2-repository</id>
	   <name>WSO2 Maven2 Repository</name>
	   <url>http://dist.wso2.org/maven2</url>
	   <snapshots>
	     <enabled>false</enabled>
	   </snapshots>
	   <releases>
		 <enabled>true</enabled>
		 <updatePolicy>never</updatePolicy>
		 <checksumPolicy>fail</checksumPolicy>
	   </releases>
	</repository>
</repositories>


Alternatively, you can download the JAR file from the following location, copy it to the repository/component/lib directory, and restart the ESB:

https://svn.wso2.org/reposgithub.com/wso2/carbon/platform/tags/turing-chunk07/products/esb/4.8.1product-esb/blob/v4.9.0/modules/samples/integration-scenarios/starbucks_sample/bin/WSO2-REST-BasicAuth-Handler-1.0-SNAPSHOT.jar

You can now send a request to the secured API. For example, you can send it using cURL as the REST client:

...

The custom handler must extend AbstractHandler and implement ManagedLifecycle as shown in the following example. You can download the Maven project for this example at https://github.com/wso2-docs/ESB/tree/master/ESB-Artifacts/OAuthHandler_Sample

Code Block
languagejava
package org.wso2.handler;

import org.apache.axis2.AxisFault;
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.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHeaders;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO;
import org.apache.synapse.ManagedLifecycle;
import org.apache.synapse.MessageContext;
import org.apache.synapse.core.SynapseEnvironment;
import org.apache.synapse.rest.AbstractHandler;
import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO_OAuth2AccessToken;

import java.util.Map;

public class SimpleOAuthHandlerSimpleOauthHandler extends AbstractHandler implements ManagedLifecycle {
   

    private static final String CONSUMER_KEY_HEADER = "Bearer";
    private static final String OAUTH_HEADER_SPLITTER = ",";
    private static final String CONSUMER_KEY_SEGMENT_DELIMITER = " ";
    private static final String OAUTH_TOKEN_VALIDATOR_SERVICE = "oauth2TokenValidationService";
    private static final String IDP_LOGIN_USERNAME = "identityServerUserName";
    private static final String IDP_LOGIN_PASSWORD = "identityServerPw";
    private ConfigurationContext configContext;
    private static final Log log = LogFactory.getLog(SimpleOAuthHandlerSimpleOauthHandler.class);
 

      @Override
    public boolean handleRequest(MessageContext msgCtx) {
        if (this.getConfigContext() == null) {
            log.error("Configuration Context is null");
            return false;
        }
        try{
            //Read parameters from axis2.xml
            String identityServerUrl =
                    msgCtx.getConfiguration().getAxisConfiguration().getParameter(
                            OAUTH_TOKEN_VALIDATOR_SERVICE).getValue().toString();
            String username =
                    msgCtx.getConfiguration().getAxisConfiguration().getParameter(
                            IDP_LOGIN_USERNAME).getValue().toString();
            String password =
                    msgCtx.getConfiguration().getAxisConfiguration().getParameter(
                            IDP_LOGIN_PASSWORD).getValue().toString();
            OAuth2TokenValidationServiceStub stub =
                    new OAuth2TokenValidationServiceStub(this.getConfigContext(), identityServerUrl);
            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 = this.createOAuthValidatorDTO(msgCtx);
            return stub.validate(dto).getValid();
        }catch(Exception e){
            log.error("Error occurred while processing the message", e);
            return false;
        }
    }
    private OAuth2TokenValidationRequestDTO createOAuthValidatorDTO(MessageContext msgCtx) {
        OAuth2TokenValidationRequestDTO dto = new OAuth2TokenValidationRequestDTO();
        Map headers = (Map) ((Axis2MessageContext) msgCtx).getAxis2MessageContext().
                getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
        String apiKey = null;
        if (headers != null) {
            apiKey = extractCustomerKeyFromAuthHeader(headers);
        }
        OAuth2TokenValidationRequestDTO_OAuth2AccessToken token =
                new OAuth2TokenValidationRequestDTO_OAuth2AccessToken();
        token.setTokenType("bearer");
        token.setIdentifier(apiKey);
        dto.setAccessToken(token);
        return dto;
    }
    private String extractCustomerKeyFromAuthHeader(Map headersMap) {
        //From 1.0.7 version of this component onwards remove the OAuth authorization header from
        // the message is configurable. So we dont need to remove headers at this point.
        String authHeader = (String) headersMap.get(HttpHeaders.AUTHORIZATION);
        if (authHeader == null) {
            return null;
        }
        if (authHeader.startsWith("OAuth ") || authHeader.startsWith("oauth ")) {
            authHeader = authHeader.substring(authHeader.indexOf("o"));
        }
        String[] headers = authHeader.split(OAUTH_HEADER_SPLITTER);
        if (headers != null) {
            for (String header : headers) {
                String[] elements = header.split(CONSUMER_KEY_SEGMENT_DELIMITER);
                if (elements != null && elements.length > 1) {
                    boolean isConsumerKeyHeaderAvailable = false;
                    for (String element : elements) {
                        if (!"".equals(element.trim())) {
                            if (CONSUMER_KEY_HEADER.equals(element.trim())) {
                                isConsumerKeyHeaderAvailable = true;
                            } else if (isConsumerKeyHeaderAvailable) {
                                return removeLeadingAndTrailing(element.trim());
                            }
                        }
                    }
                }
            }
        }
        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) {
        try {
            this.configContext =
                    ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
        } catch (AxisFault axisFault) {
            log.error("Error occurred while initializing Configuration Context", axisFault);
        }
    }
    @Override
    public void destroy() {
        this.configContext = null;
    }
    private ConfigurationContext getConfigContext() {
        return configContext;
    }
}

...

  1. In the ESB Management Console, go to Manage -> Service Bus and click Source View.
  2. Insert the following XML configuration into the source view before the closing </definitions> tag to create the TestGoogle API:

    Code Block
    languagehtml/xml
     <api xmlns="http://ws.apache.org/ns/synapse"
         name="TestGoogle"
         context="/search">
       <resource methods="GET">
          <inSequence>
             <log level="full">
               <property name="STATUS" value="***** REQUEST HITS IN SEQUENCE *****"/>
             </log>
             <send>
                <endpoint>
                   <http method="get" uri-template="https://www.google.lk/search?q=wso2"/>
                </endpoint>
             </send>
          </inSequence>
       </resource>
       <handlers>
           <handler class="org.wso2.handler.SimpleOAuthHandlerSimpleOauthHandler"/>
       </handlers>
    </api>

    Notice that the <handlers> tag contains the reference to the custom handler class.

  3. Copy the custom handler.jar to the <ESB_HOME>/repository/components/libs directory.
  4. Open <ESB_HOME>/repository/conf/axis2/axis2.xml and add the following parameters:

    Code Block
    languagehtml/xml
    <!-- OAuth2 Token Validation Service -->
    <parameter name="oauth2TokenValidationService">https://localhost:9444/services/OAuth2TokenValidationService</parameter>
    <!-- Server credentials -->
    <parameter name="identityServerUserName">admin</parameter>
    <parameter name="identityServerPw">admin</parameter>
  5. Restart the ESB.

...

  1. Start WSO2 Identity Server and log into the management console.Click Manage -> OAuth and create an OAuth application
  2. On the Main tab, click Add under Service Providers, and then add a service provider.
  3. Note the access token URL and embed it in a cURL request to get the token. For example, use the following command and replace <client-id> and <client secret> with the actual values:

    curl -v -k -X POST --user <client-id>:<client secret> -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -d 'grant_type=password&username=admin&password=admin' https://localhost:9444/oauth2/token

...

Code Block
languagebash
 curl -v -k -H "Authorization: Basic YWRtaW46YWRtaW4=" https://localhost:8243/stockquote/view/IBM  

 

 

...