Contact Us 1-800-596-4880

Mule STS Oauth 2.0 Example Application

This example Mule application behaves as a Web service provider offering its API to an external consumer.

Importing, then Running the Applications

Two for One

The Mule STS Oauth 2.0 Example Application consists of two applications:

  • one that acts as the Web service provider (Tweetbook)

  • one that acts as the Web service consumer (Bookstore).

To examine a functional example, you must import and run both the Tweetbook and Bookstore applications, the former in Mule Studio, the latter in Mule ESB Standalone.

To demonstrate the functionality of Oauth 2.0 as it applies to a Web service provider, in this document we examine only the details of the Tweetbook application.

Import and Run Bookstore

  1. If you do not already have Mule ESB Enterprise Standalone installed on your system, download Mule ESB 3.3 Enterprise trial Runtime.

  2. Download the Mule Bookstore application from the following link:
    Mule Bookstore

  3. Navigate to your downloads folder, then unpack the bookstore-oauth2-consumer.zip file you downloaded.

  4. Copy the unpacked folder bookstore-oauth2-consumer to <MULE_HOME>/apps

    <MULE_HOME> is the value of the MULE_HOME variable employed by MULE ESB, usually the root directory of the Mule ESB installation, such as /opt/Mule/mule-standalone-3.3.1/.
  5. Start Mule.

Need more detail? For Unix/Linux:

There are different ways to start the Mule server:

Option 1: Double-click the mule file located in the /bin directory beneath where you unzipped the software

This will start the Mule server by opening a command line window and running Mule "attached" to the terminal as a foreground process. The advantage of this approach is that the progress and status of the startup will echo to the command line window. The disadvantage of this approach is that this command line window will not accept any other commands until the Mule server has been stopped. This means that Shutting Down the Mule Server, you must open a new command window.

Option 2: Use the command line

It is possible to run the Mule server from the command line as follows: <MULE_HOME>/bin/mule start

This will run Mule as a background process. The advantage of this approach is that the terminal window can be closed and the process will continue to run. The disadvantage of this approach is that, in order to see the status of the startup, you will need to open a separate command line window and navigate to <MULE_HOME>/logs and execute the following command: tail mule_ee.log

Need more detail? For Windows:

There are different ways to start the Mule server:

  • Option 1: Double-click the mule file located in the \bin directory beneath where you unzipped the software package.

  • Option 2: Use the command line

On a Windows system, go to the <MULE_HOME>\bin by running <MULE_HOME>\bin then type mule and press enter. Alternatively, run mule.bat to start the server.

After it starts, Mule polls the apps folder every 5 seconds. When you copy the bookstore-oauth2-consumer application to the folder, Mule detects it and deploys it automatically. In the command line, Mule notifies you that it has deployed the application.

 ***            - - + APPLICATION + - -            * - - + STATUS + - - ** bookstore-oauth2-consumer-1                   * DEPLOYED           ** mmc                                           * DEPLOYED           ** default                                       * DEPLOYED           ** 00_mmc-agent                                  * DEPLOYED           ***INFO  2012-10-29 15:40:57,516 [WrapperListener_start_runner] org.mule.module.launcher.DeploymentService: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Mule is up and kicking (every 5000ms)                    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Import and Run Tweetbook

  1. Download the Mule Tweetbook application from the following link:
    Tweetbook

  2. Navigate to your downloads folder, then uncompress the tweetbook-oauth2-provider.zip file you downloaded.

  3. Launch Mule Studio.

  4. Under the File menu, select Import…​

  5. In the Import wizard, expand the Mule folder, then select Mule Studio Project from External Location, then click Next.

  6. In the Project Root field, use the ellipsis (. . .) button to navigate to your downloads folder, then select the tweetbook-oauth2-provider folder.

  7. Click Finish to initiate import. Studio opens the tweetbook-oauth2-provider project and displays the application in the canvas.

  8. In the Package Explorer, right-click the project name, then select Run As > Mule Application.

    Studio may display a benign warning that reads:

    Errors exist in required project(s):
     tweetbook-oauth2-provider
     Proceed with launch?

    Click OK to proceed. Studio should launch and run the Tweetbook application without issue.

  9. Studio runs the application, displaying its activities in the Studio console.

Witness the Working Example

With both the Bookstore and Tweetbook applications running, complete the following steps to experience the example applications' behavior as though a Bookstore user.

  1. To access the Bookstore website in your browser, go to the following URL: http://localhost:8085/bookstore

    welcome_bookstore
  2. Click the Your Tweetbook Account link to sign in with Tweetbook.

  3. Bookstore opens a Tweetbook login in window.

    login_tweetbook
  4. In the Username and Password fields, enter the following login credentials:

    • username = john

    • password = doe

    Notice that on this page, Tweetbook not only requests your login credentials, but simultaneously requests your permission, as the user, to share read-only access to your PROFILE and BOOKSHELF. Tweetbook could have requested user login, then requested permission to share data, but in this case, Tweetbook combines both requests in one user activity.
  5. Click Login and Authorize.

  6. Tweetbook grants the Bookstore application access to your profile and bookshelf data. Bookstore imports the data, then logs you into your new user account on Bookstore. Then, Bookstore displays the contents of your Tweetbook bookshelf.

    logged_in_bookstore

Shutting Down the Mule Server

To stop Mule ESB from running via the command line, execute the command <MULE_HOME>/bin/mule stop

Note for Unix/Linux Users

If the Mule process is attached to the terminal (run as a foreground process), the command <MULE_HOME>/bin/mule stop must be executed in a separate command line window. If, however, the Mule process has been detached from the terminal (if you started the Mule server with the <MULE_HOME>/bin/mule start command, then you can execute the command `<MULE_HOME>/bin/mule stop `from any terminal window.

How It Works

The Web service provider is a Mule application called Tweetbook. Tweetbook users keep a list of books they have read in a virtual library in their account, and can share their library and reviews with other Tweetbook users in a readers’ social network.

Bookstore is an online retailer of books. End users who wish to purchase books and who are Tweetbook users can choose to create a Bookstore account using their Tweetbook account credentials. Should a user decide to use their Tweetbook account to create an account with Bookstore, Tweetbook will share the user’s virtual library with Bookstore. Users can then consult their Tweetbook library before purchasing new books.

Tweetbook has offered its API to Bookstore and is prepared to provide read-only access to users’ profiles and virtual bookshelves.

The table below describes the OAuth entities within the context of this example.

Access Credentials

login credentials to Tweetbook

Resource Owner

the end user

Protected Resource

the end user’s account with Tweetbook

Service Provider

Tweetbook

Consumer

Bookstore

Token

token

Scope

read-only access to the end user’s profile and list of books in the virtual library

The following sections describe the OAuth dance that occurs between the service provider and consumer, and offer insight into how the Tweetbook Mule application is configured to behave as an OAuth service provider.

The OAuth Dance

  1. Before they can dance, the consumer and service provider must set the following parameters:

    • The service provider must define itself as an Oauth 2.0 service provider.

    • The consumer must register its Client ID with the provider. (The service provider stores the IDs of registered consumers in its object store.)

      pre_reqs
  2. On the Bookstore’s website, the end user — a Tweetbook account holder — decides to create a new account using his Tweetbook account credentials. The user clicks on the “Sign in with Tweetbook!” link that Bookstore makes available for this purpose.

  3. Tweetbook and Bookstore use the Authorization Grant Type to perform the OAuth dance. The Bookstore directs the user to a URL to log in to his Tweetbook account. In this step, Bookstore calls Tweetbook’s authorization server and provides its client ID (so Tweetbook knows which consumer is asking to dance). The user enters his Tweetbook login credentials. When he clicks Login and Authorize, he not only accesses his Tweetbook account, he also authorizes Tweetbook to share read-only access of his profile and bookshelf with Bookstore. Tweetbook sends Bookstore an authorization code.

    heres_my_clientID
  4. Bookstore calls Tweetbook’s authorization server again to request permission to access the protected resource (the user’s Tweetbook account). Bookstore provides its authorization code, client ID and client secret.

    ask_permission
  5. Tweetbook grants permission to access the protected resource by providing a token. Within the token, it defines the scope (i.e. specific data) which Bookstore may access. In this case, the scope is read-only access to the user’s profile and virtual bookshelf.

    heres_your_token
  6. Bookstore calls Tweetbook’s resource server to request the user’s protected resource. It offers the token Tweetbook provided as both proof of its identity and its authorization to acquire the resource.

    ask_assets
  7. Tweetbook accepts the token, then gives Bookstore the user’s profile and bookshelf information.

    heres_the_asset

  8. Bookstore allows the user to enter his new account where his virtual bookshelf is pre-populated with the list of books in his Tweetbook account.

    logged_in

Authorization Grant Type

There are four ways that a consumer can obtain authorization to dance with an OAuth service provider.

  1. Authorization Code

  2. Implicit

  3. Resource Owner Password Credentials

  4. Client Credentials

This example application uses the Authorization Code grant type which, as described above, involves a multi-step process to authorize sharing of a protected resource. For a service provider, this grant type involves the use of both an authorization server (responsible for confirming and granting permission to access the protected resource) and a resource server (responsible for providing access to the protected resource). A consumer must ask for a service provider’s permission to ask for protected resources — like a suitor asking a chaperone’s permission to ask a woman to dance. If the chaperone (authorization server) grants permission to ask, the suitor (consumer) may then ask the woman (resource server) to dance.

Refer to Authorization Grant Types for more information on the other types of authorization grants.

Oauth 2.0 Configuration in Tweetbook

This section describes the details of the example within the context of Mule Studio, Mule ESB’s graphical user interface (GUI). The XML configuration follows the Studio interface screenshot in an expandable section.

The Tweetbook application uses the Mule Secure Token Service to apply Oauth 2.0 to the API it exposes. By including the OAuth2 message processor in the Web service’s flow, Tweetbook defines itself as an OAuth2 service provider and enables Mule to perform the OAuth dance with consumers.

tweetbook oauth2 provider

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http"
  xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:oauth2-provider="http://www.mulesoft.org/schema/mule/oauth2-provider"
    xmlns:spring="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security"
    xmlns:ss="http://www.springframework.org/schema/security"
    xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/oauth2-provider http://www.mulesoft.org/schema/mule/oauth2-provider/1.0/mule-oauth2-provider.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-current.xsd
http://www.mulesoft.org/schema/mule/spring-security http://www.mulesoft.org/schema/mule/spring-security/current/mule-spring-security.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd " version="EE-3.3.1">

    <context:property-placeholder location="bookstore.properties" />
    <spring:beans>
        <ss:authentication-manager id="resourceOwnerAuthenticationManager">
            <ss:authentication-provider>
                <ss:user-service id="resourceOwnerUserService">
                    <ss:user name="john" password="doe" authorities="RESOURCE_OWNER"/>
                </ss:user-service>
            </ss:authentication-provider>
        </ss:authentication-manager>
    </spring:beans>

    <mule-ss:security-manager>
        <mule-ss:delegate-security-provider name="resourceOwnerSecurityProvider" delegate-ref="resourceOwnerAuthenticationManager"/>
    </mule-ss:security-manager>

    <oauth2-provider:config
        name="oauth2Provider"
        providerName="TweetBook"

        port="8084"
        authorizationEndpointPath="tweetbook/api/authorize"
        accessTokenEndpointPath="tweetbook/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_PROFILE WRITE_PROFILE READ_BOOKSHELF WRITE_BOOKSHELF" doc:name="Oauth2 Provider">
            <oauth2-provider:clients>
                <oauth2-provider:client clientId="${client_id}" secret="${client_secret}"
                                        type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore">
                    <oauth2-provider:redirect-uris>
                        <oauth2-provider:redirect-uri>http://localhost*</oauth2-provider:redirect-uri>
                    </oauth2-provider:redirect-uris>
                    <oauth2-provider:authorized-grant-types>
                        <oauth2-provider:authorized-grant-type>AUTHORIZATION_CODE</oauth2-provider:authorized-grant-type>
                    </oauth2-provider:authorized-grant-types>
                    <oauth2-provider:scopes>
                        <oauth2-provider:scope>READ_PROFILE</oauth2-provider:scope>
                        <oauth2-provider:scope>READ_BOOKSHELF</oauth2-provider:scope>
                        <oauth2-provider:scope>WRITE_BOOKSHELF</oauth2-provider:scope>
                        <oauth2-provider:scope>WRITE_PROFILE</oauth2-provider:scope>
                    </oauth2-provider:scopes>
                </oauth2-provider:client>
            </oauth2-provider:clients>
    </oauth2-provider:config>

    <flow name="publicProfile" doc:name="publicProfile">
        <http:inbound-endpoint address="http://localhost:8084/tweetbook/api/profile" exchange-pattern="request-response" doc:name="Profile API"/>
        <oauth2-provider:validate scopes="READ_PROFILE" config-ref="oauth2Provider" doc:name="Oauth2 Provider"/>
        <component class="org.mule.security.examples.oauth2.ProfileLookupComponent" doc:name="Profile Lookup"/>
    </flow>

    <flow name="publicBookshelf" doc:name="publicBookshelf">
        <http:inbound-endpoint address="http://localhost:8084/tweetbook/api/bookshelf" exchange-pattern="request-response" doc:name="Bookshelf API"/>
        <oauth2-provider:validate scopes="READ_BOOKSHELF" config-ref="oauth2Provider" doc:name="Oauth2 Provider"/>
        <set-payload value="The Lord of the Rings,The Hitchhiker's Guide to the Galaxy" doc:name="Retrieve Bookshelf"/>
    </flow>
</mule>