Nav
You are viewing an older version of this section. Click here to navigate to the latest version.

Using a Connector to Access an OAuth API

Mule offers a sizable collection of connectors that you can insert into flows and use in a plug-and-play fashion. In some cases, these connectors make use of an OAuth security protocol to manage user identities. In these cases, using the connector involves a few additional steps. This document outlines the steps to configure a connector to use OAuth so as to communicate with an OAuth API.

Assumptions

This document assumes that you are familiar with the Visual Editor in Anypoint Studio, Anypoint Connectors, and  Global Elements. Review the Anypoint Fundamentals to learn more about developing with Mule ESB’s graphical user interface.

OAuth Overview

OAuth (Open standard for Authorization) is a method for allowing an application to have limited access to a protected resource via a third-party API. In other words, OAuth provides a secure way for a Web service to gain limited, temporary access to a resource, such as a user account, via another Web service.

OAuth allows an API provider to:

  • Grant consumers of the API limited access to secure data

  • Avoid disclosing an end user’s access credentials to an API consumer

  • Retain the authority to revoke the consumer’s access to an end user’s secure data at any time

There are currently two versions of OAuth that are generally in use: OAuth1 and OAuth2. This document explains the process for working with OAuth2. OAuth1 implementation details vary from connector to connector, so please review the connector’s specific documentation if you need to consume OAuth1.

To better understand how OAuth works, begin by learning about entities involved in the communication between applications.

Access Credentials

Information one needs to access an asset, such as username and password

Resource Owner

A person or system that owns the protected resource and credentials needed to access the resource

Protected Resource

Data which a Consumer wishes to use, to which only the resource owner has access via the access credentials

Service Provider

An application or system which stores the protected resource; issues tokens to the Consumer after authenticating the resource owner and confirming authorization to access data

Consumer (Client)

A third-party application or system that needs to use the protected resource

Authorization Code

A code issued by the Service Provider after confirming the identification of a registered Consumer; exchanged with Service Provider during OAuth dance to acquire a Token

Token

Authorization that a Service Provider gives to a Consumer to use the protected resource; (the token does not contain the protected resource or access credentials)

Refresh Token

Credentials that a Service Provider issues to a Consumer to obtain access to a protected resource again when the original Token expires or becomes invalid; (facilitates access to the protected resource without performing the whole dance again)

Scope

An identifier in the token that defines the specific data to which the consumer has access

Adding OAuth to an online interaction is like giving a parking attendant the valet key to your rental car. You don’t want the parking attendant to access the laptop you have stored in your trunk, but you do want him to park your car for you (limited use of the protected resource). As the resource owner, you could give the attendant your car key (access credentials) to park your car, but with the key, he could also open the trunk and take your laptop. Luckily, the car rental company (the service provider) provided a valet key (token) that enables the attendant to start the car (scope), but does not allow him to access the trunk.

Access Credentials

Car key

Resource Owner

You

Protected Resource

Car

Service Provider

Rental car company

Consumer

Parking attendant

Token

Valet key

Scope

Ability to drive the car, but not access the trunk

In the online world, adding OAuth to an online activity gives a Web service permission to use some of the information in an online private account an end user maintains with another Web service. For example, say you have just discovered a new website that issues online invitations for events. You are anxious to use this service for your upcoming party for 100 friends, but you do not want to enter the email addresses of 100 invitees into the online invitation website. You have already entered them into your online address book on another website. Luckily, the invitation website can use OAuth to solve the problem.

Because it wants to make your life easier, the invitation website gives you the option of importing all your contacts from another website. You (resource owner) can click a button to access your account (protected resource) on the daily planner website. When you click the button, the invitation website (consumer) directs you to the login page for the daily planner website (service provider). You enter your username and password (access credentials) to access your account (protected resource). After you log in, the daily planner website provides the invitation website with a token that allows the invitation website to import all of your contacts (scope), yet do nothing more (for example, it cannot change your password or access the personal calendar you have stored in the same account). The interaction between Consumer and Service provider in this context is referred to as the OAuth dance.

Access Credentials

Your username and password to your account on the daily planner website

Resource Owner

You

Protected Resource

Your account on the daily planner website

Service Provider

Daily planner website

Consumer

Invitation website

Token

Token

Scope

Access to the address book, only

Using a Connector with OAuth2

To explain how to configure a connector to use OAuth2, this document uses the example of building a Mule flow with an OAuth Salesforce connector.

Acquiring OAuth Tokens

To implement OAuth2 into your connector, you must first acquire a consumer key and a consumer secret from the application to which you intend to connect. This procedure varies from one service provider to another, so look for the documentation provided by the software service provider.

The OAuth provider (in this case, Salesforce) asks that you provide a callback URL. The callback URL is the URL that the OAuth provider calls with the authorization tokens once authorization has been completed.  Remember the URL you set here, as it must match the one your application uses.

How to Get Your Consumer Key and Secret for Salesforce

  1. Register for a Salesforce account

  2. After completing the registration, click the link in the confirmation email to set a password, then log in to Salesforce Developer Edition.

  3. Configure your Salesforce account to be accessed from a remote application using OAuth. On the Salesforce Developer Edition UI, click the Setup link on the top rigth of the screen, next to your user name.

  4. Look for the Connected Apps section, and click the New button next to it to connect a new app

  5. Fill in the form for your application, be sure to enable the checkbox labeled Enable OAuth Settings. Then provide a callback URL and list the permissions that your API should obtain.

  6. Click Save, then, on the following page, note the consumer key and consumer secret. You use these values to configure the connector to access Salesforce. 

Configuring Your Connector

In your Mule application, create and configure new connector using the following pieces of data:

  • Your consumer key

  • Your consumer secret

  • The OAuth callback URL

If you need to deploy to different environments (for example, production, development) where these parameters need to have different values, see Deploying to Multiple Environments.
  1. If you haven’t already done so, create a new Mule project, then click the Global Elements tab at the bottom of the canvas.

  2. Click Create, then expand the Connector Configurations node and select the appropriate global type that matches your OAuth-enabled connector. Click OK

    connectorconfiguration-1

  3. In the Global Element Properties panel, enter the Consumer Key and Consumer Secret with the information that the software service provider gave you.

    sfdcGE-ckcs

  4. On the OAuth tab, enter the callback URL’s Domain , Port , and Path . The example below results in a callback URL of http://localhost:8081/callback.

    oauthcallback  

Field

Example Value

Example CloudHub Value

Description

Domain

localhost

${fullDomain}

Should be the domain assigned to the listener at the start of your OAuth callback flow.  When in production, this is the domain on which your application is hosted.

Local Port

` 8081 `

${http.port}

The port on which your authorization flow is hosted. This is the port configured on your HTTP listener.

Remote Port

${fullDomain}

The port of the listener at which your OAuth callback is hosted.

Path

callback

callback

The path of the listener at which your OAuth callback is hosted.

Default Access Token Id

n/a

n/a

Not used in this example. Read more about [Managing OAuth Tokens].

Controlling Flow Processing

You can configure your connector to define the behavior of a connector when a user with no OAuth token attempts to utilize the service (that is, the user is not yet authenticated via OAuth). Use the On No Token field to select one of the following two options.

STOP_FLOW

Behaving like a filter, this option kills flow execution . This choice is ideal for keeping log files light as it doesn’t create exceptions before you have had a chance to authorize your connector to access the OAuth provider.

EXCEPTION

(Default) Throws an exception advising the user that an OAuth token is required.

sfdc-exception

  1. Configure a global Salesforce (OAuth) element according to the table below.

    
           
                    
                 
    1
    2
    
    <sfdc:config-with-oauth name="salesforce" consumerKey="[insert key]" consumerSecret="[insert secret]" doc:name="Salesforce (OAuth)">
     </sfdc:config-with-oauth>
    Global Element

    sfdc:config-with-oauth

    Attribute Value

    name

    name of the global element

    consumerKey

    consumer key as provided by service provider 

    consumerSecret

    `consumer secret as provided by service provider `

    doc:name

    Studio only. Name of the global element. 

  2. Add a child element to define the Callback URL. The example below results in a callback URL of ` http://localhost:8081/callback`.

Attribute

Example Value

Example CloudHub Value

 Description

domain

localhost

${fullDomain}

The domain of the listener on your OAuth callback flow.  When in production, this is the domain on which your application is hosted.

localPort

`8081 `

${http.port}

The port you configured on the listener of the authorization flow

remotePort

${fullDomain}

The port you configured on the listener of the OAuth callback.

path

callback

callback

The path of the listener at which your OAuth callback is hosted.

defaultAccessTokenId

n/a

n/a

Not used in this example. Read more about [Managing OAuth Tokens].

Controlling Flow Processing

You can configure your connector to define the behavior of a connector when a user with no OAuth token attempts to utilize the service (i.e. the user is not yet authenticated via OAuth). Use the onNoToken attribute to define one of the following two options.

STOP_FLOW

Behaving like a filter, this option kills flow execution. This choice is ideal for keeping log files light as it doesn’t create exceptions before you have had a chance to authorize your connector to access the OAuth provider.

EXCEPTION

(Default) Throws an exception advising the user that an OAuth token is required


     
              
           
1
2
3
<sfdc:config-with-oauth name="salesforce" consumerKey="[insert key]" consumerSecret="[insert secret]" doc:name="Salesforce (OAuth)" onNoToken="[STOP_FLOW]">
    <sfdc:oauth-callback-config domain="localhost" remotePort="8081" path="callback"/>
 </sfdc:config-with-oauth>

Creating an Authorization Flow

Before an end user application can perform any operations via the service provider’s API, it must obtain authentication to do so. To make authentication possible, use an authorization flow in your Mule application. This authorization flow requests, then acquires authentication tokens from the OAuth provider. It  consists of an HTTP listener followed by a Salesforce connector which uses the global Salesforce (OAuth) element you created to perform the authorize operation with Salesforce. 

  1. Drag building blocks onto the canvas to build a Mule flow as per below.

    salesforce+oauth

  2. Create a new connector configuration element for the HTTP connector, set the Host and Port to correspond to the callback URL that you set in your global element. (In the example, the callback URL is http://localhost:8081/callback.) In this case, also set the Path in the connector to callback.

  3. Click the Salesforce connector to open its properties editor, then use the drop-down Connector Configuration to select the global Salesforce element your created in the previous section. 

  4. Configure any additional fields required by the connector you have selected. See below for configuration details of the Salesforce connector example.

    Field Value

    Connector Configuration

    The name of the global element you created for your connector.

    Operation

    Authorize

    Access Token URL

    (Optional) See below.
    Example: ` https://na1.salesforce.com/services/oauth2/token `

    Authorization URL

    (Optional) See below.
    Example: ` https://na1.salesforce.com/services/oauth2/authorize `

    Display

    PAGE

    sfdc-pe

Access Token and Authorization URLs

Some service providers expose unique URLs to acquire access tokens and perform authorization (For example, a service provider many expose one URL for sandbox development, and one URL for production).

Attribute Description

Authorization URL

_(Optional) _Defined by the service provider, the URL to which the resource owner is redirected to grant authorization to the connector.

Access Token URL

(Optional) Defined by the service provider, the URL to obtain an access token.

Access Token Id

(Optional) (Default value: connector configuration name)
The OAuth accessTokenId within which Mule stores tokens.

Scopes

Depending on the service provider, you may have the option to define scopes . A scope gives you access to perform a set of particular actions, such as viewing contacts, posting items, changing passwords, etc. The Salesforce connector does not use scopes.

Should a connectors require scope configuration, Studio includes the scopes as configurable fields in the properties editor. If the connector you wish to use makes use of scopes , refer to the connector’s specific documentation to determine which values are valid.

  1. Create an authorization flow, starting with an HTTP listener. Set the values of attributes according to the tables below. 

    Element

    http:listener

    Attribute Value

    config-ref

    HTTP_Listener_Configuration

    path

    localhost

  2. Create a global configuration element for the HTTP Listener

    Element

    http:listener-config

    Attribute Value

    name

    HTTP_Listener_Configuration

    path

    localhost

    port *

    8081

    *The port must correspond to the remotePort`attribute in your `oauth-callback-config.

  3. Add a Salesforce connector to the flow. Set the values of attributes according to the tables below. 

    Element

    sfdc:authorize

    Attribute Value

    config-ref

    The name of the global element you created for your connector.

    accessTokenUrl

    (Optional ) See below. ` `Example: `https://na1.salesforce.com/services/oauth2/token `

    authorizationUrl

    (Optional ) See below. ` `Example: ` https://na1.salesforce.com/services/oauth2/authorize `

    display

    PAGE


    
            
         
1
2
3
4
5
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8081"/>
<flow name="OAuthTestFlow1" doc:name="OAuthTestFlow1">
    <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP Connector"/>
    <sfdc:authorize config-ref="Salesforce__OAuth_" display="PAGE" doc:name="Salesforce" accessTokenUrl="https://na1.salesforce.com/services/oauth2/token" authorizationUrl="https://na1.salesforce.com/services/oauth2/authorize"/>
</flow>

Access Token and Authorization URLs

Some service providers expose unique URLs to acquire access tokens and perform authorization (For example, a service provider many expose one URL for sandbox development, and one URL for production).

Attribute Description

authorizationUrl

_(Optional) _Defined by the service provider, the URL to which the resource owner is redirected to grant authorization to the connector.

accessTokenUrl

(Optional) Defined by the service provider, the URL to obtain an access token.

accessTokenId

(Optional) (Default value: connector configuration name.)
The OAuth accessTokenId within which Mule stores tokens.

Scopes

Depending on the service provider, you may have the option to define scopes. A scope gives you access to perform a set of particular actions, such as viewing contacts, posting items, changing passwords, etc. The Salesforce connector does not use scopes.

Should a connectors require scope configuration, Studio includes the scopes as configurable fields in the properties editor. If the connector you wish to use makes use of scopes, refer to the connector’s specific documentation to determine which values are valid.

About the Authorization Flow

An end user initiates the authorization flow above by navigating to the HTTP Listener’s address in a Web browser. When triggered, this flow starts the OAuth dance, directing the user to the service provider’s login page. Mule also creates a callback endpoint so the service provider can direct the user back to the Mule flow once authenticated. The connector extracts information from the callback, sets its own internal state to authorized, then continues flow processing. Further, the connector automatically issues an access token identifier which Mule stores in the ObjectStore.  

Mule manages access tokens automatically assigning a default value for the ` accessTokenId ` to match the name of the global connector configuration (in this example, the global Salesforce (OAuth) element). Using a default value allows  the connector to be authorized for many users. However, because CloudHub’s ObjectStore functionality behaves slightly differently, if you run your project in CloudHub in multitenancy mode, then each access token identifier is unique for each user. Note that on all versions of Mule prior to Mule Studio (October 2013) with CloudHub Mule Runtime (October 2013), you must perform a few extra steps to manage storage of the accessTokenId.

After Authentication

Add a Logger element to your flow after the connector set to the authorization operation. If the connector is not yet authorized, Mule delays execution of the logger until it receives a callback. On the other hand, if the user has already been authorized in a previous request and the connector already has its TokenId, then Mule continues flow execution and the logger executes immediately, rather than waiting for the callback.

  1. Drag a Logger message processor from the palette to the canvas and place it after the Salesforce connector.

    salesforce+oauth+2

  2. Open the Logger’s properties, then add a message for the Logger to output. For example: "The connector has been properly authorized."

    connectorauthorized

  1. Add a logger element into your flow, including a message attribute, the value of which indicates the Logger’s output.


    
             
          
1
<logger message="The connector has been properly authorized." level="INFO" doc:name="Logger"/>

Full Example


     
              
           
1
2
3
4
5
6
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8081"/>
<flow name="OAuthTestFlow1" doc:name="OAuthTestFlow1">
    <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP Connector"/>
    <sfdc:authorize config-ref="Salesforce__OAuth_" display="PAGE" accessTokenUrl="https://na1.salesforce.com/services/oauth2/token" authorizationUrl="https://na1.salesforce.com/services/oauth2/authorize"/>
    <logger message="The connector has been properly authorized." level="INFO" doc:name="Logger"/>
</flow>

Managing OAuth Tokens

Mule stores Token IDs in an Object Store variable. Optionally, you can define the name of this variable according to three different behaviors:

  1. Using the connector’s config name (Default)

  2. using the expression set as the value of ` defaultAccessTokenId ` attribute

  3. using the value of the ` AccessTokenId ` attribute to set an operation

The following list explains each of these behaviors.

  1. Mule uses the connector’s config name by default. If your config looks like the example below, the Object Store variable that keeps track of Token IDs also uses the name Box_Connector. This functionality is available whether running on CloudHub, or in single-tenant mode on premises.

    
                
             
    1
    2
    3
    4
    5
    6
    7
    8
    
    <box:config name="Box_Connector" clientId="123" clientSecret="123" doc:name="Box"  >
        <box:oauth-callback-config domain="localhost" localPort="8081" path="box_callback" remotePort="8081"/>
    </box:config>
     
    <flow name="flow1">
        <box:authorize />
        <box:upload-stream />
    </flow>

    When running on-premises implementations, leaving this variable’s name to its default could lead to token overwriting when multiple users access the service. If you have ten users then you cannot store their ten, unique Token IDs under the same variable name. In such a case, you must create new variables for each.

    However, this issue does not manifest when running in multitenant mode on CloudHub. In CloudHub, each tenant gets its own separate Object Store partition which is completely unaccessible for other tenants. For example, if you have ten customers, those ten tokens are in different partitions of the Object Store and so keys don’t overlap. 

  2. If you set the defaultAccessTokenId parameter in the connector’s config, Mule uses its value. You can set this parameter to an expression to avoid overwriting the Token ID.

    box-ge

    
        
                   
                
    1
    2
    3
    4
    5
    6
    7
    8
    
    &lt;box:config name="Box_Connector" clientId="123" clientSecret="123" doc:name="Box"  &gt;
        &lt;box:oauth-callback-config domain="localhost" localPort="8081" path="box_callback" remotePort="8081" defaultAccessTokenId="#[message.inboundProperties.tenantId]"/&gt;
    &lt;/box:config&gt;
     
    &lt;flow name="flow1"&gt;
        &lt;box:authorize /&gt;
        &lt;box:upload-stream /&gt;
    &lt;/flow&gt;
  3. Set an operation in an AccessTokenId attribute to override everything else for this operation. Keep in mind that this attribute only affects the current operation; other operations for the same connector use the default operation unless otherwise specified. 


         
      
1
2
3
4
<flow name="flow1">
    <box:authorize accessTokenId="#[flowVars.myTenantId]"/>
    <box:upload-stream accessTokenId="#[flowVars.myTenantId]"/>
</flow>

See Also