Nav

Creating an Oauth 2.0 Web Service Provider

The primary responsibility of an OAuth2 Web service provider is to control access to protected resources. Playing the part of both the Authorization server and the Resource server, the OAuth provider module hosts the protected resources and issues tokens to access protected resources without sharing the resource owner’s credentials with the client applications. 

The service provider in the OAuth dance performs the following tasks:

  • Provides a login page for resource owners to enter login credentials

  • Authenticates clients, both CONFIDENTIAL and PUBLIC

  • Authenticates the resource owner’s credentials

  • Issues and validates authorization codes

  • Provides tokens, which specify the data to which a client may have access (scope)

  • Validates tokens, thereby granting access to a protected resource

  • Issues refresh tokens to clients

For a detailed explanation of the OAuth dance, see the Mule STS Oauth 2.0 Example Application.

Assumptions

This topic introduces the idea of Global Elements; if you are unfamiliar with this functionality, access Global Elements to learn more before proceeding. It is assumed that you’re familiar with the OAuth dance and OAuth2 grant types.

Oauth 2.0 Elements

Mule provides two elements that enable you to configure a Web service provider capable of completing the tasks listed above.

Element Description Studio Visual Editor XML

Global OAuth Element

A global element in which you specify most of the configuration settings for the provider, such as login page details, security providers, whether to issue refresh tokens, token lifespan, and supported grant types and scopes. This global element is meant to be referenced by message processors.

The Coding Reference attribute in any OAuth Provider Module Message Processor refers to this.

<oauth2-provider:config />

Validate

Configure to validate tokens, confirming that the client presents the correct scopes to access the protected resource.

Add an OAuth Provider Message Processor and set the  operation attribute to Validate

<oauth2-provider:validate />

Because the OAuth provider module message processor only issues tokens to registered clients, Mule also offers two methods for registering clients: 

  1. You can manually define a list of registered clients during the configuration of your Mule application. 

  2. You can enable clients to register dynamically in the Mule application.

The OAuth provider module itself does not generate client IDs or secrets. These are generated by another mechanism, for a example a Web page with a form that validates user input, then generates the ID and secret. After generating the ID and secret, this mechanism – the Web page in this example – simply passes the information to the OAuth provider module, which uses the data to keep track of clients registered to use the service.

With respect to registering clients, then, the OAuth provider module is responsible for the following tasks:

  • Accepting and storing the client ID

  • Accepting and storing the client secret

  • Removing, when necessary, a client ID from the clientStore of registered clients (Version 1.2 only)

  • Revoking access or refresh tokens (Version 1.2 only)

Mule provides three elements to complete the above-listed tasks: 

Element Description Studio Visual Editor XML

Create client

Accepts and stores the client data, including ID, secret, redirection URIs, scopes, and grant types in the clientStore. (the clientStore could be a database or the default persistent object store, depending on your requirements.)

Add an OAuth Provider Message Processor and set the operation attribute to create client.

<oauth2-provider:create-client />

Delete ClientVersion 1.2 only

Removes clientIDs from the clientStore.

Add an OAuth Provider Message Processor and set the operation attribute to delete client.

<oauth2-provider:delete-client />

Revoke Token – Version 1.2 only

Revokes access or refresh tokens, invalidating the corresponding pair as well (i.e. if the message processor revokes the access token, it automatically revokes any refresh token associated with it, and vice versa).

Add an OAuth Provider Message Processor and set the operation attribute to revoke token.

<oauth2-provider:revoke-token />

Applying Oauth 2.0 to a Web Service Provider

To apply Oauth 2.0 to a Web service that you publish, you must complete, at minimum, five tasks. The first two tasks Defining Resources which the OAuth Provider elements reference; the last three apply Oauth 2.0 to Mule flows, initiating OAuth2 authentication when a consumer calls the Web service. The table below lists these tasks, along with the Mule elements involved in each task and the OAuth tasks for which each element is responsible.

Task Mule Element OAuth Tasks

1.

Create a Spring bean to define an authentication manager and provider

Spring bean

Performs client authentication

2.

Configure a security manager

Mule Security Manager

Delegates client authentication

3.

Create a Global Oauth 2.0 provider to define several OAuth parameters

Global OAuth provider element

Defines most of the service provider’s OAuth 2.0 parameters

4.

Create a Client Registration flow

OAuth provider module configured to Create Client

Stores client IDs and secrets

5.

Create OAuth Validation flows

OAuth provider module configured to Validate or` Validate-client`

Validates the access token, thereby granting, or rejecting, access to a protected resource.

Paths to Authentication

Before tackling the work of creating an Oauth 2.0 Web service, it is important to understand the various ways in which a service provider can authenticate a client.

When a client calls an OAuth Web service, it must identify itself by one of two types: PUBLIC or CONFIDENTIAL.

  • A PUBLIC client provides a client ID which the Web service provider uses for authentication

  • A CONFIDENTIAL client provides validation credentials (client ID and client secret) which the Web service provider uses for authentication

If CONFIDENTIAL, a client must provide validation credentials in one of three different parts of the request:

  • In the query

  • In the body

  • In the *authentication header*Therefore, you must configure your Oauth 2.0 Web service provider to match the type(s) of client requests you expect to receive. The figure below illustrates the different types of requests and their resulting paths to authentication.

    client_validation

    If the client sends validation credentials in the body or the query of the request, the OAuth Web service provider simply validates the incoming credentials (client ID and client secret) against the content in the clientStore. If, on the other hand, the client sends validation credentials in the authentication header of the request, the service provider uses a security manager to delegate authentication to an authentication manager. The authentication manager users an authentication provider to validate a client’s principals (username and password, for example).

Defining Resources

The following procedure describes the steps you need to take in order to define the resources that the OAuth Provider and Global OAuth Provider reference.

To define OAuth provider resources, complete the steps listed below.

  1. Within your Web service project in Mule, create a Spring bean called ss-authentication manager, in which you define the authentication-provider. It will essentially be a database of the users that are allowed.

    
                
             
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <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>

    Refer to the Spring Security documentation for different ways of configuring the authentication database.

  2. Within your Web service project in Mule, create a security manager element which references the authentication manager. (In the context of an OAuth Web service, the authentication manager is the security provider.)

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

    The OAuth 2.0 provider enables you to configure two security providers: resourceOwnerSecurityProvider and clientSecurityProvider.

    resourceOwnerSecurityProvider authenticates resource owners (eg: when the user credentials are validated after the login page). The only situation where this provider is not required, is when the Grant Type is Client Credentials.

    clientSecurityProvider validates client credentials, it’s only needed when a client is confidential AND has a client secret. Whenever the client credentials are sent on the authorization header, you need this provider to delegate the authentication.

Creating an OAuth Provider Global Element

A Global Element in Mule is an element that stores common configuration settings. A global element can be referenced by any number of message processors, which in this way use the configuration settings of the global element.

  1. Add an OAuth Provider module message processor to your Mule project.

  2. Configure the attributes of the message processor according to the table below the image. The "Required" column indicates that an attribute is required for validating a client app and resource owner. (Refer to example code below.)

    OAuth_provider

    Field Required Value

    Name

    A unique name for the global element.

    Access Token Endpoint Path

    Configures the path of the access token endpoint required to access resource server.
    Default value: token

    Host

    Web service host used for the generated authorization, token and login endpoints.
    Default value: localhost

    Provider Name

    Name of the Web service provider. For example, TweetBook. This is displayed in the login page.

    Authorization Ttl Seconds

    Lifespan of authorization code in seconds.
    Default value: 600

    Port

    Port on which the Web service is exposed. The authorization endpoint and the token endpoint listen on this port.
    Default value: 9999

    Client Store Reference

    In-memory store that retains OAuth client-specific information. Use this field to reference a specific element that implements the ClientStore interface, typically an object store.
    Default value: in-memory object store 

    Authorization Code Store Reference

    In-memory store that retains OAuth client-specific information. Use this field to reference a specific element that implements the AuthorizationCodeStore interface, typically an object store.
    Default value: in-memory object store

    Token Store Reference

    In-memory store that retains OAuth client-specific information. Use this field to reference a specific element that implements the TokenStore interface, typically an object store.
    Default value: in-memory object store

    Authorization Endpoint Path

    Configures the path of the authorization endpoint required to access resource server.
    Default value: authorize

    Login Page

    URL for the service provider’s end user login page. The resource owner logs into her account from this page.
    Default value: org/mule/modules/oauth2/provider/www/templates/login.html 

    Scopes

    x

    A space-separated list that defines a set of scopes of data to which to provide access. Consumers may then be limited to access certain scopes only.

    Example: READ_PROFILE WRITE_PROFILE READ_BOOKSHELF WRITE_BOOKSHELF

    Token Ttl Seconds

    Lifespan of token in seconds.
    Default value: 86400

    Connector Reference

    A reference to the type of transport, which defaults to HTTP. If your application uses something other than HTTP – Jetty, HTTPS, Servlet – or you have some specific HTTP transport configurations you wish to reference, use this field to reference a specific connector.

    Resource Owner Security Provider Reference

    x

    The reference to the authentication server’s security provider. For example, resourceOwnerSecurityProvider references the Spring security manager (which, in turn, references the authentication manager Spring bean).

    If the only configured grant type is Client Credentials, then this field is not required.

    Client Security Provider Reference

    The reference to the security provider that validates client credentials.

    Supported Grant Types

    Space-separated list of authorization grant types that the OAuth Web service provider supports. Specify one of the values listed below.  See the section below for more details.
    AUTHORIZATION_CODE (default)
    IMPLICIT
    RESOURCE_OWNER_PASSWORD_CREDENTIALS
    CLIENT_CREDENTIALS 

    Rate Limiter Reference

    References a package to define limitations for the rate at which a client can call the interface. By default, references org.mule.modules.oauth2.provider.rateLimit.SimpleInMemmoryRateLimiter.
    Use the class to set maximumFailureCount (default = 5) and authResetAfterSeconds (default = 600).

    Enable Refresh Token

    Set to TRUE, this attribute allows Mule to send refresh tokens.
    Default value: FALSE

    URIs for accessing endpoints are be built following the structure below:

    
           
                   
                
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    &lt;oauth2-provider:config
            name="oauth2Provider"
            providerName="TweetBook"
            host="localhost"
            port="${http.port}"
            authorizationEndpointPath="tweetbook/oauth/authorize"
            accessTokenEndpointPath="tweetbook/oauth/token"
            resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
            scopes="READ_PROFILE WRITE_PROFILE READ_BOOKSHELF WRITE_BOOKSHELF" doc:name="OAuth provider module"&gt;
        &lt;/oauth2-provider:config&gt;
  1. Add a global oauth2-provider:config to your Mule application, at the top of your XML config file, outside all flows.

    
           
                   
                
    1
    
    &lt;oauth2-provider:config/&gt;

    Add attributes to the global element according to the table below. The Required column indicates an attribute is required for validating a client app and resource owner. (Refer to example code below.)

    
           
                   
                
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    &lt;oauth2-provider:config
            name="oauth2Provider"
            providerName="TweetBook"
            host="localhost"
            port="${http.port}"
            authorizationEndpointPath="tweetbook/oauth/authorize"
            accessTokenEndpointPath="tweetbook/oauth/token"
            resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
            scopes="READ_PROFILE WRITE_PROFILE READ_BOOKSHELF WRITE_BOOKSHELF" doc:name="OAuth provider module"&gt;
        &lt;/oauth2-provider:config&gt;
    Attribute Required Value

    doc:name

    A unique name for the global element.

    accessTokenEndpointPath

    Configures the path of the access token endpoint required to access resource server.
    Default value: token

    host

    Web service host used for the generated authorization, token and login endpoints.
    Default value: localhost

    providerName

    Name of the Web service provider, it is displayed in the log in page. For example, TweetBook

    authorizationTtlSeconds

    Lifespan of authorization code in seconds.
    Default value: 600

    port

    Port on which the Web service is exposed. Both the authorization endpoint and the token endpoint listen on this port.
    Default value: 9999

    clientStoreReference

    In-memory store that retains OAuth client-specific information. Use this field to reference a specific element that implements the ClientStore interface, typically an object store.
    Default value: persistent object store

    authorizationCodeStoreReference

    In-memory store that retains OAuth client-specific information. Use this field to reference a specific element that implements the AuthorizationCodeStore interface, typically an object store.
    Default value: persistent object store

    tokenStoreReference

    In-memory store that retains OAuth client-specific information. Use this field to reference a specific element that implements the TokenStore interface, typically an object store.
    Default value: persistent object store

    authorizationEndpointPath

    Configures the path of the authorization endpoint required to access resource server.
    Default value: authorize

    loginPage

    URL for the service provider’s end user login page. The resource owner logs into her account from this page.
    Default value: org/mule/modules/oauth2/provider/www/templates/login.html

    scopes

    A space-separated list that defines a set of scopes of data to which to provide access. Consumers may then be limited to access certain scopes only.

    Example: READ_PROFILE WRITE_PROFILE READ_BOOKSHELF WRITE_BOOKSHELF

    tokenTtlSeconds

    Lifespan of token in seconds.
    Default value: 86400

    connectorReference

    A reference to the type of transport, which defaults to HTTP. If your application uses something other than HTTP – Jetty, HTTPS, Servlet – or you have some specific HTTP transport configurations you wish to reference, use this field to reference a specific connector.

    resourceOwnerSecurityProvider

    The reference to the authentication server’s security provider. For example, resourceOwnerSecurityProvider references the Spring security manager (which, in turn, references the authentication manager Spring bean).

    If the only configured grant type is Cient Credentials, then this field is not required.

    clientSecurityProvider

    The reference to the security provider that validates client credentials.

    supportedGrantTypes

    Space-separated list of authorization grant types the OAuth Web service provider supports. Specify one of the values listed below. See the section below for more details.
    AUTHORIZATION_CODE (default)
    IMPLICIT
    RESOURCE_OWNER_PASSWORD_CREDENTIALS
    CLIENT_CREDENTIALS 

    rateLimiterReference

    References a package to define limitations for the rate at which a client can call the interface. By default, references org.mule.modules.oauth2.provider.rateLimit.SimpleInMemmoryRateLimiter
    Use the class to set maximumFailureCount (default = 5) and authResetAfterSeconds (default = 600).

    enableRefreshToken

    Set to TRUE, this attribute allows Mule to send refresh tokens.
    Default value: FALSE

URIs for accessing endpoints are be built following the structure below:

OAuth Grant Types

OAuth provides four basic grant types that the client can use to validate itself when it requests for a token. Each of these grant types requires a specific configuration of the OAuth Provider Global Element.

If unsure about the difference between each grant type, and when to use each type, you can glean some context from the introduction to the OAuth2 spec.

The Authorization Code grant type is meant for general use and is the most secure of all the grant types.

To implement authorization code, clients need to define the following pieces of information:

  • Client ID

  • Client Secret

  • Redirect URL

Below is a simple typical configuration of an oauth2 module with an authorization code client:


    
            
         
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
&lt;oauth2-provider:config
        name="oauth2Provider"
        providerName="SampleAPI"
        supportedGrantTypes="AUTHORIZATION_CODE"
        port="8081"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module"&gt;
            &lt;oauth2-provider:clients&gt;
                &lt;oauth2-provider:client clientId="myclientid" secret="myclientsecret"
                                        type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore"&gt;
                    &lt;oauth2-provider:redirect-uris&gt;
                        &lt;oauth2-provider:redirect-uri&gt;http://localhost*&lt;/oauth2-provider:redirect-uri&gt;
                    &lt;/oauth2-provider:redirect-uris&gt;
                    &lt;oauth2-provider:authorized-grant-types&gt;
                        &lt;oauth2-provider:authorized-grant-type&gt;AUTHORIZATION_CODE&lt;/oauth2-provider:authorized-grant-type&gt;
                    &lt;/oauth2-provider:authorized-grant-types&gt;
                    &lt;oauth2-provider:scopes&gt;
                        &lt;oauth2-provider:scope&gt;READ_RESOURCE&lt;/oauth2-provider:scope&gt;
                        &lt;oauth2-provider:scope&gt;POST_RESOURCE&lt;/oauth2-provider:scope&gt;
                    &lt;/oauth2-provider:scopes&gt;
                &lt;/oauth2-provider:client&gt;
            &lt;/oauth2-provider:clients&gt;
    &lt;/oauth2-provider:config&gt;

In order to test this example, you need to perform an OAuth2 dance with several steps:

  1. You must first invoke the authorization endpoint with a request that includes the client id, the type of authorization you want to perform, the redirect URL, and the scopes you want to authorize. The structure of the request should look like the URI below:

    
           
                   
                
    1
    
    http://localhost:8081/sampleapi/api/authorize?response_type=code&amp;client_id=myclientid&amp;scope=READ_RESOURCE&amp;redirect_uri=http://localhost:8081/redirect
  2. This displays the login page in the browser. Once the user has successfully logged in, the provider sends a redirect to the specified redirect_uri. This redirect includes additional properties, including an access code.

  3. You then need to send this code to the token endpoint in a request that also includes the client id, the client secret and some of the information in the previous call, for security reasons. The structure of the request should look like the URI below:

    
           
                   
                
    1
    
    http://localhost:8081/sampleapi/api/token?grant_type=authorization_code&amp;client_id=myclientid&amp;client_secret=myclientsecret&amp;code=&lt;use here the access code&gt;&amp;redirect_uri=http://localhost:8081/redirect
  4. If everything works correctly, you get a JSON response like the one below:

    
           
                   
                
    1
    2
    3
    4
    5
    6
    
    {
        "scope":"READ_RESOURCE",
        "expires_in":86400,
        "token_type":"bearer",
        "access_token":"huig0RVoGdFoz_mvBaV4ovfjj0Afe8yOAp_v2q0tunevsJVpD2HNRhx8lL6JnMDys7KE3O4TfijknWPzGJZ-NA"
    }
  5. You can now include the access_token as a header in your requests to access to protected resources:

    
           
                   
                
    1
    
    access_token=huig0RVoGdFoz_mvBaV4ovfjj0Afe8yOAp_v2q0tunevsJVpD2HNRhx8lL6JnMDys7KE3O4TfijknWPzGJZ-NA

The implicit grant type is not as secure as the authorization code grant type. It is mostly used by Javascript clients and mobile applications. It is simpler than the authorization code in terms of the steps that need to be followed, since the authorization server directly issues an access token instead of an intermediate access code.

Below is a simple typical configuration of an OAuth2 module with an implicit grant client:


    
            
         
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
&lt;oauth2-provider:config
        name="oauth2Provider"
        providerName="SampleAPI"
        supportedGrantTypes="IMPLICIT"
        port="8082"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module"&gt;
            &lt;oauth2-provider:clients&gt;
                &lt;oauth2-provider:client clientId="myclientid2" secret="myclientsecret"
                                        type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore"&gt;
                    &lt;oauth2-provider:redirect-uris&gt;
                        &lt;oauth2-provider:redirect-uri&gt;http://localhost*&lt;/oauth2-provider:redirect-uri&gt;
                    &lt;/oauth2-provider:redirect-uris&gt;
                    &lt;oauth2-provider:authorized-grant-types&gt;
                        &lt;oauth2-provider:authorized-grant-type&gt;TOKEN&lt;/oauth2-provider:authorized-grant-type&gt;
                    &lt;/oauth2-provider:authorized-grant-types&gt;
                    &lt;oauth2-provider:scopes&gt;
                        &lt;oauth2-provider:scope&gt;READ_RESOURCE&lt;/oauth2-provider:scope&gt;
                        &lt;oauth2-provider:scope&gt;POST_RESOURCE&lt;/oauth2-provider:scope&gt;
                    &lt;/oauth2-provider:scopes&gt;
                &lt;/oauth2-provider:client&gt;
            &lt;/oauth2-provider:clients&gt;
    &lt;/oauth2-provider:config&gt;

To see a full working Mule flow that includes this configuration


         
                 
              
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
 
&lt;mule xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:core="http://www.mulesoft.org/schema/mule/core"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security" xmlns:ss="http://www.springframework.org/schema/security"
xmlns:oauth2-provider="http://www.mulesoft.org/schema/mule/oauth2-provider"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.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
http://www.mulesoft.org/schema/mule/oauth2-provider http://www.mulesoft.org/schema/mule/oauth2-provider/current/mule-oauth2-provider.xsd"&gt;
     
 
    &lt;oauth2-provider:config
        name="oauth2ProviderImplicit"
        providerName="SampleAPI"
        supportedGrantTypes="IMPLICIT"
        port="8082"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module"&gt;
            &lt;oauth2-provider:clients&gt;
                &lt;oauth2-provider:client clientId="myclientid2" secret="myclientsecret"
                                        type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore"&gt;
                    &lt;oauth2-provider:redirect-uris&gt;
                        &lt;oauth2-provider:redirect-uri&gt;http://localhost*&lt;/oauth2-provider:redirect-uri&gt;
                    &lt;/oauth2-provider:redirect-uris&gt;
                    &lt;oauth2-provider:authorized-grant-types&gt;
                        &lt;oauth2-provider:authorized-grant-type&gt;TOKEN&lt;/oauth2-provider:authorized-grant-type&gt;
                    &lt;/oauth2-provider:authorized-grant-types&gt;
                    &lt;oauth2-provider:scopes&gt;
                        &lt;oauth2-provider:scope&gt;READ_RESOURCE&lt;/oauth2-provider:scope&gt;
                        &lt;oauth2-provider:scope&gt;POST_RESOURCE&lt;/oauth2-provider:scope&gt;
                    &lt;/oauth2-provider:scopes&gt;
                &lt;/oauth2-provider:client&gt;
            &lt;/oauth2-provider:clients&gt;
    &lt;/oauth2-provider:config&gt;
    &lt;http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8082" doc:name="HTTP Listener Configuration"/&gt;
 
    &lt;flow name="protected-implicit" doc:name="DemoRestRouterFlow1"&gt;
        &lt;http:listener config-ref="HTTP_Listener_Configuration" path="/resources" doc:name="HTTP"/&gt;    
        &lt;oauth2-provider:validate config-ref="oauth2ProviderImplicit" doc:name="Validate Token" scopes="READ_RESOURCE"/&gt;
        &lt;set-payload value="#[ ['name' : 'payroll', 'uri' : 'http://localhost:8081/resources/payroll'] ]" doc:name="Set Payload"/&gt;
        &lt;json:object-to-json-transformer doc:name="Object to JSON"/&gt;
    &lt;/flow&gt;
     
&lt;/mule&gt;

In order to test this example, you need to follow the steps of a simplified OAuth dance:

  1. Invoke the authorization endpoint with a request that includes the client id, the type of authorization you want to perform, the redirect URL, and the scopes you want to authorize. The structure of the request should look like the URI below:

    
           
                   
                
    1
    
    http://localhost:8082/sampleapi/api/authorize?response_type=token&amp;client_id=myclientid2&amp;scope=READ_RESOURCE&amp;redirect_uri=http://localhost:8082/redirect 
  2. This displays the login page in the browser. Once the user has successfully logged in, the provider sends a redirect to the specified redirect_uri. This redirect already includes the token itself (not just an access code). It should look like this:

    
           
                   
                
    1
    
    http://localhost:8082/redirect#access_token=d8gI_X7TLuAmYuZvlt0wx7sq1tnNgI9Ku9DazKAJYWXbB9QNzSTNxnXCeg75x5zZzT4zAcuCVkit6oBHkoSFow&amp;token_type=bearer&amp;expires_in=86399&amp;scope=READ_RESOURCE
  3. You can now include the access_token as a header in your requests to access to protected resources:

    
           
                   
                
    1
    
    access_token=huig0RVoGdFoz_mvBaV4ovfjj0Afe8yOAp_v2q0tunevsJVpD2HNRhx8lL6JnMDys7KE3O4TfijknWPzGJZ-NA

The resource owner password credentials grant type is less secure than both the implicit and the authorization code grant types, because the client needs to have the ability to handle the user’s credentials. This requires that users have a high degree of trust in the client. This grant type is normally used when the consumer of the protected resource is a widget of the same service, and other similar cases.

Below is a simple typical configuration of an OAuth2 module with resource owner password credentials:


    
            
         
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
&lt;oauth2-provider:config
        name="oauth2Provider"
        providerName="SampleAPI"
        supportedGrantTypes="RESOURCE_OWNER_PASSWORD_CREDENTIALS"
        port="8083"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module"&gt;
            &lt;oauth2-provider:clients&gt;
                &lt;oauth2-provider:client clientId="myclientid3" secret="myclientsecret"
                                        type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore"&gt;
                    &lt;oauth2-provider:redirect-uris&gt;
                        &lt;oauth2-provider:redirect-uri&gt;http://localhost*&lt;/oauth2-provider:redirect-uri&gt;
                    &lt;/oauth2-provider:redirect-uris&gt;
                    &lt;oauth2-provider:authorized-grant-types&gt;
                        &lt;oauth2-provider:authorized-grant-type&gt;PASSWORD&lt;/oauth2-provider:authorized-grant-type&gt;
                    &lt;/oauth2-provider:authorized-grant-types&gt;
                    &lt;oauth2-provider:scopes&gt;
                        &lt;oauth2-provider:scope&gt;READ_RESOURCE&lt;/oauth2-provider:scope&gt;
                        &lt;oauth2-provider:scope&gt;POST_RESOURCE&lt;/oauth2-provider:scope&gt;
                    &lt;/oauth2-provider:scopes&gt;
                &lt;/oauth2-provider:client&gt;
            &lt;/oauth2-provider:clients&gt;
    &lt;/oauth2-provider:config&gt;

To see a full working Mule flow that includes this configuration


         
                 
              
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
 
&lt;mule xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:core="http://www.mulesoft.org/schema/mule/core"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security" xmlns:ss="http://www.springframework.org/schema/security"
xmlns:oauth2-provider="http://www.mulesoft.org/schema/mule/oauth2-provider"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.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
http://www.mulesoft.org/schema/mule/oauth2-provider http://www.mulesoft.org/schema/mule/oauth2-provider/current/mule-oauth2-provider.xsd"&gt;
     
 
    &lt;oauth2-provider:config
        name="oauth2ProviderRopc"
        providerName="SampleAPI"
        supportedGrantTypes="RESOURCE_OWNER_PASSWORD_CREDENTIALS"
        port="8083"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module"&gt;
            &lt;oauth2-provider:clients&gt;
                &lt;oauth2-provider:client clientId="myclientid3" secret="myclientsecret"
                                        type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore"&gt;
                    &lt;oauth2-provider:redirect-uris&gt;
                        &lt;oauth2-provider:redirect-uri&gt;http://localhost*&lt;/oauth2-provider:redirect-uri&gt;
                    &lt;/oauth2-provider:redirect-uris&gt;
                    &lt;oauth2-provider:authorized-grant-types&gt;
                        &lt;oauth2-provider:authorized-grant-type&gt;PASSWORD&lt;/oauth2-provider:authorized-grant-type&gt;
                        &lt;oauth2-provider:authorized-grant-type&gt;AUTHORIZATION_CODE&lt;/oauth2-provider:authorized-grant-type&gt;
                    &lt;/oauth2-provider:authorized-grant-types&gt;
                    &lt;oauth2-provider:scopes&gt;
                        &lt;oauth2-provider:scope&gt;READ_RESOURCE&lt;/oauth2-provider:scope&gt;
                        &lt;oauth2-provider:scope&gt;POST_RESOURCE&lt;/oauth2-provider:scope&gt;
                    &lt;/oauth2-provider:scopes&gt;
                &lt;/oauth2-provider:client&gt;
            &lt;/oauth2-provider:clients&gt;
    &lt;/oauth2-provider:config&gt;
    &lt;http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8083" doc:name="HTTP Listener Configuration"/&gt;
    &lt;flow name="protected-ropwc" doc:name="DemoRestRouterFlow1"&gt;
        &lt;http:listener config-ref="HTTP_Listener_Configuration" path="/resources" doc:name="HTTP"/&gt;        
        &lt;oauth2-provider:validate config-ref="oauth2ProviderRopc" doc:name="Validate Token" scopes="READ_RESOURCE"/&gt;
        &lt;set-payload value="#[ ['name' : 'payroll', 'uri' : 'http://localhost:8081/resources/payroll'] ]" doc:name="Set Payload"/&gt;
        &lt;json:object-to-json-transformer doc:name="Object to JSON"/&gt;
    &lt;/flow&gt;
     
&lt;/mule&gt;

To test this example:

  1. Send a POST request to the token endpoint that includes the user name and password. The request should look like the one below:

    
           
                   
                
    1
    2
    3
    4
    5
    6
    
    POST /sampleapi/api/token HTTP/1.1
    Host: localhost:8083
    Cache-Control: no-cache
    Content-Type: application/x-www-form-urlencoded
     
    grant_type=password&amp;username=john&amp;password=doe&amp;client_id=myclientid3&amp;client_secret=myclientsecret&amp;scope=READ_RESOURCE

    To make this request, use a browser extension such as Postman (Google Chrome), or the curl command line utility.

  2. If everything works correctly, you will get a JSON response like the one below:

    
           
                   
                
    1
    2
    3
    4
    5
    6
    
    {
        "scope": "READ_RESOURCE",
        "expires_in": 86399,
        "token_type": "bearer",
        "access_token": "sgFJ8Y3VPcMOdldrFtCMcWe8VQLdOA8L6pcrqjTYA6L3G9bTIDiOFkiiSC2lmFx-RUKtkzTupW0ugU49hqHhpg"
    }
  3. You can now include the access_token as a header in your requests to access to protected resources:

    
           
                   
                
    1
    
    access_token=sgFJ8Y3VPcMOdldrFtCMcWe8VQLdOA8L6pcrqjTYA6L3G9bTIDiOFkiiSC2lmFx-RUKtkzTupW0ugU49hqHhpg

The client credentials grant type is the least secure of all the four types defined by the standard. It is generally meant for being used when the client is also resource owner or when an authorization has previosly been arranged with the authorization server. In this grant type an access token may be obtained drectly from the client identifier and the client secret.

Below is a simple typical configuration of an OAuth2 module with client credentials:


    
            
         
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
&lt;oauth2-provider:config
        name="oauth2Provider"
        providerName="SampleAPI"
        supportedGrantTypes="CLIENT_CREDENTIALS"
        port="8084"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module"&gt;
            &lt;oauth2-provider:clients&gt;
                &lt;oauth2-provider:client clientId="myclientid4" secret="myclientsecret"
                                        type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore"&gt;
                    &lt;oauth2-provider:redirect-uris&gt;
                        &lt;oauth2-provider:redirect-uri&gt;http://localhost*&lt;/oauth2-provider:redirect-uri&gt;
                    &lt;/oauth2-provider:redirect-uris&gt;
                    &lt;oauth2-provider:authorized-grant-types&gt;
                        &lt;oauth2-provider:authorized-grant-type&gt;CLIENT_CREDENTIALS&lt;/oauth2-provider:authorized-grant-type&gt;
                    &lt;/oauth2-provider:authorized-grant-types&gt;
                    &lt;oauth2-provider:scopes&gt;
                        &lt;oauth2-provider:scope&gt;READ_RESOURCE&lt;/oauth2-provider:scope&gt;
                        &lt;oauth2-provider:scope&gt;POST_RESOURCE&lt;/oauth2-provider:scope&gt;
                    &lt;/oauth2-provider:scopes&gt;
                &lt;/oauth2-provider:client&gt;
            &lt;/oauth2-provider:clients&gt;
    &lt;/oauth2-provider:config&gt;

Click to see a full working Mule flow that includes this configuration


    
            
         
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
 
&lt;mule xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:core="http://www.mulesoft.org/schema/mule/core"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security" xmlns:ss="http://www.springframework.org/schema/security"
xmlns:oauth2-provider="http://www.mulesoft.org/schema/mule/oauth2-provider"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.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
http://www.mulesoft.org/schema/mule/oauth2-provider http://www.mulesoft.org/schema/mule/oauth2-provider/current/mule-oauth2-provider.xsd"&gt;
     
 
    &lt;oauth2-provider:config
        name="oauth2ProviderClientCreds"
        providerName="SampleAPI"
        supportedGrantTypes="CLIENT_CREDENTIALS"
        port="8084"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module"&gt;
            &lt;oauth2-provider:clients&gt;
                &lt;oauth2-provider:client clientId="myclientid4" secret="myclientsecret"
                                        type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore"&gt;
                    &lt;oauth2-provider:redirect-uris&gt;
                        &lt;oauth2-provider:redirect-uri&gt;http://localhost*&lt;/oauth2-provider:redirect-uri&gt;
                    &lt;/oauth2-provider:redirect-uris&gt;
                    &lt;oauth2-provider:authorized-grant-types&gt;
                        &lt;oauth2-provider:authorized-grant-type&gt;CLIENT_CREDENTIALS&lt;/oauth2-provider:authorized-grant-type&gt;
                    &lt;/oauth2-provider:authorized-grant-types&gt;
                    &lt;oauth2-provider:scopes&gt;
                        &lt;oauth2-provider:scope&gt;READ_RESOURCE&lt;/oauth2-provider:scope&gt;
                        &lt;oauth2-provider:scope&gt;POST_RESOURCE&lt;/oauth2-provider:scope&gt;
                    &lt;/oauth2-provider:scopes&gt;
                &lt;/oauth2-provider:client&gt;
            &lt;/oauth2-provider:clients&gt;
    &lt;/oauth2-provider:config&gt;
 
    &lt;http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8082" doc:name="HTTP Listener Configuration"/&gt;
    &lt;flow name="protected-client-creds" doc:name="DemoRestRouterFlow1"&gt;
        &lt;http:listener config-ref="HTTP_Listener_Configuration" path="/resources" doc:name="HTTP"/&gt;    
        &lt;oauth2-provider:validate config-ref="oauth2ProviderClientCreds" doc:name="Validate Token" scopes="READ_RESOURCE"/&gt;
        &lt;set-payload value="#[ ['name' : 'payroll', 'uri' : 'http://localhost:8081/resources/payroll'] ]" doc:name="Set Payload"/&gt;
        &lt;json:object-to-json-transformer doc:name="Object to JSON"/&gt;
    &lt;/flow&gt;
     
&lt;/mule&gt;

To test this example:

  1. Send a POST request to the token endpoint that includes the user name and password. The request should look like one below:

    
           
                   
                
    1
    2
    3
    4
    5
    6
    
    POST /sampleapi/api/token HTTP/1.1
    Host: localhost:8082
    Cache-Control: no-cache
    Content-Type: application/x-www-form-urlencoded
     
    grant_type=client_credentials&amp;client_id=myclientid4&amp;client_secret=myclientsecret&amp;scope=READ_RESOURCE

    To make this request use a browser extension such as Postman (Google Chrome), or the curl command line utility.

  2. If everything works correctly, you should get a JSON response like the one below:

    
           
                   
                
    1
    2
    3
    4
    5
    6
    
    {
        "scope": "READ_RESOURCE",
        "expires_in": 86400,
        "token_type": "bearer",
        "access_token": "4juchYVW5ZNNSH_OOU0jxziixjdJ7yhdZTJW5tbi80cJO3oAF-lTD6D05gw2EKA9yxUuOLf-f_oVBX6z0aRI9w"
    }
  3. You can now include the access_token as a header in your requests to access to protected resources:

    access_token=4juchYVW5ZNNSH_OOU0jxziixjdJ7yhdZTJW5tbi80cJO3oAF-lTD6D05gw2EKA9yxUuOLf-f_oVBX6z0aRI9w

Creating a Client Registration Flow

Recall that in order to use a Web service protected by Oauth 2.0, a client must first register with the service. The following procedure describes the steps needed to configure a Mule flow to dynamically accept client registration requests.

  1. Create a new Mule flow with an inbound connector.

  2. Use one of three following methods to store client IDs and secrets.

    1. Add an OAuth provider module message processor to the flow which will accept and store client IDs and secrets. Configure the element’s fields according to the table below.

      oauth1

      Field Required Value

      Display Name

      Enter a unique name for the global element.

      Config Reference

      x

      Reference the global OAuth provider module element you created above.

      Operation

      x

      Create client

      Client Id

      x

      Define where to acquire the client ID. (In the example code below, Mule accesses an object store to validate the client_ID and client_secret.) Use a Mule expression to dynamically accept this information from clients.

      Client Name

      Identify the client application by name.

      Description

      Offer a brief description of the client application.

      Principal

      Defines a client’s principals (username and password, for example).

      Secret

      Define where to acquire the client secret.
      Not a required attribute if the type is PUBLIC.

      Type

      Define the client type (PUBLIC or CONFIDENTIAL).

      Strings

      Select Create A List, then click the (plus) icon to add an oauth2-provider:authorized-grant-types child element to the oauth2-provider:create-client element in your config. In the dialog, click Define, then enter one or more of the following values, separated by spaces:

      AUTHORIZATION_CODE IMPLICIT RESOURCE_OWNER_PASSWORD_CREDENTIALS CLIENT_CREDENTIALS 

      Strings

      Select Create A List, then click the (plus) icon to add an oauth2-provider:redirect-uris child element to the oauth2-provider:create-client element in your config. In the dialog, click Define, then enter a URI to which the message processor redirects an authorization code.

      During registration, a client indicates which are its valid redirect URIs. When the client later requests an authorization code, it also includes a redirect URI. If the redirect URI included in the request for authorization code is valid (i.e. matches one of the redirect URIs submitted by the client during registration), the message processor directs the authorization code to the specified URI.

      Strings

      Select Create A List, then click the (plus) icon to add an oauth2-provider:scopes child element to the oauth2-provider:create-client element in your config. In the dialog, click Define, then enter a space-separated list of scopes which the client must provide when it uses the service.

      See the code example below. Notice that Mule creates a default object store, then loads clients' information into that object store.

      
                
                        
                     
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      
      &lt;oauth2-provider:config
              ...
                  &lt;oauth2-provider:clients&gt;
                      &lt;oauth2-provider:client clientId="${client_id}" secret="${client_secret}"
                                              type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore"&gt;
                          &lt;oauth2-provider:redirect-uris&gt;
                              &lt;oauth2-provider:redirect-uri&gt;http://oauth-consumer.qa.cloudhub.io*&lt;/oauth2-provider:redirect-uri&gt;
                          &lt;/oauth2-provider:redirect-uris&gt;
                          &lt;oauth2-provider:authorized-grant-types&gt;
                              &lt;oauth2-provider:authorized-grant-type&gt;AUTHORIZATION_CODE&lt;/oauth2-provider:authorized-grant-type&gt;
                          &lt;/oauth2-provider:authorized-grant-types&gt;
                          &lt;oauth2-provider:scopes&gt;
                              &lt;oauth2-provider:scope&gt;READ_PROFILE&lt;/oauth2-provider:scope&gt;
                              &lt;oauth2-provider:scope&gt;READ_BOOKSHELF&lt;/oauth2-provider:scope&gt;
                              &lt;oauth2-provider:scope&gt;WRITE_BOOKSHELF&lt;/oauth2-provider:scope&gt;
                              &lt;oauth2-provider:scope&gt;WRITE_PROFILE&lt;/oauth2-provider:scope&gt;
                          &lt;/oauth2-provider:scopes&gt;
                      &lt;/oauth2-provider:client&gt;
                  &lt;/oauth2-provider:clients&gt;
          &lt;/oauth2-provider:config&gt;
    2. Add a Spring bean and write Java code to be referenced by it, using the default object store. In order to do this you must use the XML Console. In the example code below, the Spring bean invokes the initialize method of the TweetBookInitializer Java class. Mule generates the value of the default object store, then the Spring bean sets that value on the `clientRegistration `property.

      
                
                        
                     
      1
      2
      3
      
      &lt;spring:bean class="org.mule.modules.security.examples.oauth2.TweetBookInitializer"
                           init-method="initialize"
                           p:clientRegistration="#{oauth2Provider.configuration.clientStore}" /&gt;
      
                
                        
                     
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      
      public class TweetBookInitializer
      {
          public static final String BOOKSTORE_CLIENT_ID = "e7aaf348-f08a-11e1-9237-96c6dd6a022f";
          public static final String BOOKSTORE_CLIENT_SECRET = "ee9acaa2-f08a-11e1-bc20-96c6dd6a022f";
       
          private ClientRegistration clientRegistration;
       
          public void initialize()
          {
              final Client bookstoreClient = new Client(BOOKSTORE_CLIENT_ID);
              bookstoreClient.setSecret(BOOKSTORE_CLIENT_SECRET);
              bookstoreClient.setType(ClientType.CONFIDENTIAL);
              bookstoreClient.setClientName("Mule Bookstore");
              bookstoreClient.setDescription("Mule-powered On-line Bookstore");
              bookstoreClient.getAuthorizedGrantTypes().add(RequestGrantType.AUTHORIZATION_CODE);
              bookstoreClient.getRedirectUris().add("http://localhost*");
              bookstoreClient.getScopes().addAll(
                  Utils.tokenize("READ_PROFILE READ_BOOKSHELF WRITE_BOOKSHELF WRITE_PROFILE"));
       
              clientRegistration.addClient(bookstoreClient);
          }
       
          public void setClientRegistration(final ClientRegistration clientRegistration)
          {
              this.clientRegistration = clientRegistration;
          }
      }
    3. Create a custom implementation of the object store to store client data, which includes IDs and secrets.

      1. Create an implementation of the `org.mule.modules.oauth2.provider.client.ClientStore `interface

      2. In the XML configuration, add a clientStore-ref property to the oauth2-provider:create-client element. Mule invokes the getClientById method of the contract to obtain client IDs and secrets.

  1. Create a new Mule flow with an inbound connector.

  2. Use one of three following methods to store client IDs and secrets.

    1. Add an oauth2-provider:client-create element to the flow in your Mule application which will accept and store client IDs and secrets. See code example below, notice that Mule creates a default object store, then loads the clients' information into that object store.)

      
                
                        
                     
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      
      &lt;oauth2-provider:create-client clientId="${client_id}" secret="${client_secret}"
                                              type="CONFIDENTIAL" clientName="Mule Bookstore" description="Mule-powered On-line Bookstore"&gt;
          &lt;oauth2-provider:redirect-uris&gt;
          &lt;oauth2-provider:redirect-uri&gt;http://oauth-consumer.qa.cloudhub.io*&lt;/oauth2-provider:redirect-uri&gt;
          &lt;/oauth2-provider:redirect-uris&gt;
          &lt;oauth2-provider:authorized-grant-types&gt;
              &lt;oauth2-provider:authorized-grant-type&gt;AUTHORIZATION_CODE&lt;/oauth2-provider:authorized-grant-type&gt;
          &lt;/oauth2-provider:authorized-grant-types&gt;
          &lt;oauth2-provider:scopes&gt;
              &lt;oauth2-provider:scope&gt;READ_PROFILE&lt;/oauth2-provider:scope&gt;
              &lt;oauth2-provider:scope&gt;READ_BOOKSHELF&lt;/oauth2-provider:scope&gt;
              &lt;oauth2-provider:scope&gt;WRITE_BOOKSHELF&lt;/oauth2-provider:scope&gt;
              &lt;oauth2-provider:scope&gt;WRITE_PROFILE&lt;/oauth2-provider:scope&gt;
          &lt;/oauth2-provider:scopes&gt;
      &lt;/oauth2-provider:create-client&gt;

      Configure the element’s attributes according to the table below:

      Attribute Required Value

      config-ref

      x

      Use the name of the new global OAuth provider module element you created above.

      doc:name

      A unique name for the element in the flow.

      clientId

      x

      Define where to acquire the client ID. (In the example code below, Mule access an object store to validate the client_ID and client_secret.)

      clientName

      Identify the client application.

      description

      Offer a brief description of the client application.

      secret

      x

      Define where to acquire the client secret.
      Not a required attribute if the is PUBLIC.

      type

      x

      Define the client type (PUBLIC or CONFIDENTIAL).

      Add three child elements to the oauth2-provider:create-client element in your config:

      Child Element Attribute Value

      oauth2-provider:authorized-grant-types

      ref

      Define one or more of the following values, separated by spaces:
      AUTHORIZATION_CODE IMPLICIT RESOURCE_OWNER_PASSWORD_CREDENTIALSCLIENT_CREDENTIALS 

      oauth2-provider:redirect-uris

      ref

      Identify the URI to which the message processor redirects an authorization code.
      During registration, a client indicates which are its valid redirect URIs. When the client later requests an authorization code, it also includes a redirect URI. If the redirect URI included in the request for authorization code is valid (i.e. matches one of the redirect URIs submitted by the client during registration), the message processor directs the authorization code to the specified URI.

      oauth2-provider:scopes

      ref

      Define a space-separated list of scopes which the client must provide when it uses the service.

    2. Add a Spring bean and write Java code to be referenced by it, using the default object store. In the example code below, the Spring bean invokes the initialize method of the TweetBookInitializer Java class. Mule generates the value of the default object store, then the Spring bean sets that value on the `clientRegistration `property.

      
                
                        
                     
      1
      2
      3
      
      &lt;spring:bean class="org.mule.modules.security.examples.oauth2.TweetBookInitializer"
                           init-method="initialize"
                           p:clientRegistration="#{oauth2Provider.configuration.clientStore}" /&gt;
      
                
                        
                     
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      
      public class TweetBookInitializer
      {
          public static final String BOOKSTORE_CLIENT_ID = "e7aaf348-f08a-11e1-9237-96c6dd6a022f";
          public static final String BOOKSTORE_CLIENT_SECRET = "ee9acaa2-f08a-11e1-bc20-96c6dd6a022f";
       
          private ClientRegistration clientRegistration;
       
          public void initialize()
          {
              final Client bookstoreClient = new Client(BOOKSTORE_CLIENT_ID);
              bookstoreClient.setSecret(BOOKSTORE_CLIENT_SECRET);
              bookstoreClient.setType(ClientType.CONFIDENTIAL);
              bookstoreClient.setClientName("Mule Bookstore");
              bookstoreClient.setDescription("Mule-powered On-line Bookstore");
              bookstoreClient.getAuthorizedGrantTypes().add(RequestGrantType.AUTHORIZATION_CODE);
              bookstoreClient.getRedirectUris().add("http://localhost*");
              bookstoreClient.getScopes().addAll(
                  Utils.tokenize("READ_PROFILE READ_BOOKSHELF WRITE_BOOKSHELF WRITE_PROFILE"));
       
              clientRegistration.addClient(bookstoreClient);
          }
       
          public void setClientRegistration(final ClientRegistration clientRegistration)
          {
              this.clientRegistration = clientRegistration;
          }
      }
    3. Create a custom implementation of the object store to store client data, which includes IDs and secrets.

      1. Create an implementation of the `org.mule.modules.oauth2.provider.client.ClientStore `interface

      2. Add a clientStore-ref property to the oauth2-provider:create-client element. Mule invokes the getClientById method of the contract to obtain client IDs and secrets.

Disallow Client Access

Version 1.2 only

To prevent an existing client from using the Web service, use a delete-client element in a new flow to remove the client ID from the list of registered clients.

Removing a client ID from the list of registered clients does not automatically revoke tokens related to the clientID. After removing a client from the list, you can wait for the client’s existing token – access or refresh – to expire, which thereafter bars them from using the Web service, or you can revoke the tokens manually using the revoke-token element (Revoke Token message processor in Studio’s Visual Editor).

  1. Create a new Mule flow that includes an inbound connector.

  2. Add an OAuth Provider Module after the inbound connector.

  3. Configure the attributes of the OAuth Provider Module according to the table below.

    oauth-deleteclient

    Field Required Value

    Display Name

    Enter a unique name for the global element.

    Config Reference

    x

    Reference the global OAuth provider module element you created above.

    Operation

    x

    Delete client

    Client Id

    x

    Define where to acquire the client ID. Use a Mule expression to dynamically accept this information from clients.

  4. Optionally, add a second OAuth Provider Module after the first one to revoke tokens from a client, immediately barring them from using the Web service. Then configure the attributes as per the table below.

    oauth-deletetokens

    Field Required Value

    Display Name

    Enter a unique name for the global element.

    Config Reference

    x

    Reference the global OAuth provider module element you created above.

    Operation

    x

    Revoke token

    Client Id

    x

    Define where to acquire the token. Use a Mule expression to dynamically accept this information from clients.

  1. Create a new Mule flow that includes an inbound connector.

  2. Add an oauth2-provider:delete-client element after the inbound connector.

  3. Configure a single attribute of the delete-client element according to the table below.

    Attribute Required Value

    clientId

    x

    Define the client ID to be removed from the list. See code example below.

    
           
                   
                
    1
    
    &lt;oauth2-provider:delete-client clientId="#[message.inboundProperties.clientId]"/&gt; 
  4. Optionally, add an oauth2-provider:revoke-token element to the flow to revoke tokens from a client, immediately barring them from using the Web service. Add the revoke-token message processor after the delete-client message processor, then configure the attributes as per the table below.

    Attribute Required Value

    token

    x

    A Mule expression indicating the access token to be revoked. Note that by revoking a client’s access token, Mule also revokes any refresh tokens associated with the client, and vice versa. See code example below.

    
           
                   
                
    1
    
    &lt;oauth2-provider:revoke-token token="#[message.inboundProperties.access_token]"/&gt; 

Full Code Example of User Registration and Deletion

If you copy this code into an editor, there are several fields that need to be completed with implementation-specific data.


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?xml version="1.0" encoding="UTF-8"?>
 
<mule xmlns:oauth2-provider="http://www.mulesoft.org/schema/mule/oauth2-provider" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="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.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.2/mule-oauth2-provider.xsd">
     
     
    <spring:bean id="clientsObjectStore" class="org.mule.util.store.InMemoryObjectStore" init-method="initialise" destroy-method="dispose" />
     
    <spring:bean name="clientStore"  class="org.mule.modules.oauth2.provider.client.ObjectStoreClientStore">
        <spring:property name="objectStore" ref="clientsObjectStore" />
    </spring:bean>
     
    <!-- sample for token store -->   
    <!--
    <spring:bean name="tokenStore" class="org.mule.modules.oauth2.provider.token.ObjectStoreTokenStore">
        <spring:property name="refreshTokenObjectStore" ref="clientsObjectStore" />
        <spring:property name="accessTokenObjectStore" ref="clientsObjectStore" />
    </spring:bean>
     -->
      
    <oauth2-provider:config
        name="oauth2ProviderRegister"
        providerName="SampleAPI"
        supportedGrantTypes="IMPLICIT"
        port="8085"
        clientStore-ref="clientStore"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module" />
     
    <http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8085" doc:name="HTTP Listener Configuration"/>
 
 <!-- sample flow for registering a client -->
    <flow name="register-clientsFlow1" doc:name="register-clientsFlow1">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/register" doc:name="HTTP"/> 
        <oauth2-provider:create-client config-ref="oauth2ProviderRegister" clientId="#[message.inboundProperties.clientId]" clientName="#[message.inboundProperties.clientName]" secret="#[message.inboundProperties.secret]" doc:name="OAuth provider module">
            <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_RESOURCE</oauth2-provider:scope>
                <oauth2-provider:scope>POST_RESOURCE</oauth2-provider:scope>
            </oauth2-provider:scopes>
        </oauth2-provider:create-client>
    </flow>
     
    <!-- sample flow for revoking a client -->
    <flow name="unregister-clientsFlow1" doc:name="unregister-clientsFlow1">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/unregister" doc:name="HTTP"/>   
        <oauth2-provider:delete-client config-ref="oauth2ProviderRegister" clientId="#[message.inboundProperties.clientId]" />
    </flow>
</mule>

Creating OAuth Validation Flows

The following procedure describes the steps to configure Mule flows to accept requests for protected resources. You can create a flow that allows a client app to access just one scope of a protected resource, or multiple scopes of a protected resource. (In our example application — see code below — Mule uses two flows with OAuth provider modules: one to enable clients to access the READ_PROFILE scope, one to enable clients to access the READ_BOOKSHELF scope.)

A validation flow must contain an OAuth provider module message processor which defines a few of the attributes required for an Oauth 2.0 Web service provider. Generally speaking, however, the OAuth Provider message processor in a flow behaves more like a placeholder, referencing the OAuth provider global element for the bulk of its processing instructions.

  1. Create a new Mule flow that includes an inbound connector and a connection to a protected resource.

  2. To this Mule flow, add an OAuth2 provider module message processor before the point in the flow at which Mule accesses the protected resource. In other words, set the OAuth2 provider module message processor before Mule calls a database or another service to access the resource owner’s private, secure data.

  3. Configure the attributes of the OAuth2 provider module according to the table below.

    oauth2

    oauth3

    Field Required Value

    Display Name

    Enter a unique name for the message processor in your flow.

    Config Reference

    x

    Use the name of the new global OAuth provider module element you created above.

    Operation

    x

    Set to validate for authorization grant types that utilize "three-legged OAuth" (Authorization Code, Implicit, and Resource Owner Password Credentials).

    Set to validate-client to check that the provided client credentials are valid.

    Resource Owner Roles

    Specifies resource owner roles Mule enforces when validating a token.

    Scopes

    Specifies the scopes of data to which the client app will have access.

    Throw Exception On Unaccepted

    x

    Version 1.2 only
    When set to FALSE , if the message processor encounters an invalid token, it performs two actions: it returns an HTTP FORBIDDEN 403 error, then stops the flow.
    When set to TRUE, if the message processor encounters an invalid token which Mule can manage with an exception strategy, it throwns an InvalidAccessTokenException.
    Default value: FALSE.

    
           
                   
                
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    &lt;http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8082" basePath="tweetbook/api" doc:name="HTTP Listener Configuration"/&gt;
        &lt;flow name="publicProfile" doc:name="publicProfile"&gt;
            &lt;http:listener config-ref="HTTP_Listener_Configuration" path="/profile" doc:name="HTTP"/&gt;  
            &lt;oauth2-provider:validate scopes="READ_PROFILE" config-ref="oauth2Provider" doc:name="OAuth provider module"/&gt;
            &lt;component class="org.mule.security.examples.oauth2.ProfileLookupComponent" doc:name="Profile Lookup"/&gt;
        &lt;/flow&gt;
     
        &lt;flow name="publicBookshelf" doc:name="publicBookshelf"&gt;
            &lt;http:listener config-ref="HTTP_Listener_Configuration" path="/bookshelf" doc:name="HTTP"/&gt;       
            &lt;oauth2-provider:validate scopes="READ_BOOKSHELF" config-ref="oauth2Provider" doc:name="OAuth provider module"/&gt;
            &lt;set-payload value="The Lord of the Rings,The Hitchhiker's Guide to the Galaxy" doc:name="Retrieve Bookshelf"/&gt;
        &lt;/flow&gt;
  1. Create a new Mule flow that includes an inbound connector and a connection to a protected resource.

  2. To this Mule flow, add an oauth2-provider:validate element or `oauth2-provider:validate-client `element before the point in the flow at which Mule accesses the protected resource. In other words, set the element before Mule calls a database or another service to access the resource owner’s private, secure data.

    • validate: for authorization grant types that utilize "three-legged OAuth" (Authorization Code, Implicit, and Resource Owner Password Credentials)

    • validate-client: to check that the provided client credentials are valid.

  3. Configure the attributes of the oauth2-provider element as per the table below.

    
           
                   
                
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    &lt;http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8082" basePath="tweetbook/api" doc:name="HTTP Listener Configuration"/&gt;   
        &lt;flow name="publicProfile" doc:name="publicProfile"&gt;
            &lt;http:listener config-ref="HTTP_Listener_Configuration" path="/profile" doc:name="HTTP"/&gt;  
            &lt;oauth2-provider:validate scopes="READ_PROFILE" config-ref="oauth2Provider" doc:name="OAuth provider module"/&gt;
            &lt;component class="org.mule.security.examples.oauth2.ProfileLookupComponent" doc:name="Profile Lookup"/&gt;
        &lt;/flow&gt;
     
        &lt;flow name="publicBookshelf" doc:name="publicBookshelf"&gt;
            &lt;http:listener config-ref="HTTP_Listener_Configuration" path="/bookshelf" doc:name="HTTP"/&gt;
            &lt;oauth2-provider:validate scopes="READ_BOOKSHELF" config-ref="oauth2Provider" doc:name="OAuth provider module"/&gt;
            &lt;set-payload value="The Lord of the Rings,The Hitchhiker's Guide to the Galaxy" doc:name="Retrieve Bookshelf"/&gt;
        &lt;/flow&gt;
    Attribute Required Value

    config-ref

    x

    Use the name of the new global OAuth provider module element you created above.

    doc:name

    A unique name for the element in the flow.

    resourceOwnerRoles

    Specifies resource owner roles Mule enforces when validating a token.

    scopes

    Specifies the scopes of data to which the client app will have access.

    throwExceptionOnUnaccepted

    x

    Version 1.2 only
    When set to FALSE , if the message processor encounters an invalid token, it performs two actions: it returns an HTTP FORBIDDEN 403 error, then stops the flow.

    When set to TRUE, if the message processor encounters an invalid token which Mule can manage with an exception strategy, it throwns an InvalidAccessTokenException.

Persisting Object Stores

The Oauth2 provider enables you to specify the implementation of the object stores where the clients, the tokens and the refresh tokens are stored. Here is a sample configuration on how to do this with the client store.


         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<spring:bean id="clientsObjectStore" class="org.mule.util.store.InMemoryObjectStore" init-method="initialise" destroy-method="dispose" />
     
    <spring:bean name="clientStore"  class="org.mule.modules.oauth2.provider.client.ObjectStoreClientStore">
        <spring:property name="objectStore" ref="clientsObjectStore" />
    </spring:bean>
     
    <oauth2-provider:config
        name="oauth2ProviderRegister"
        providerName="SampleAPI"
        supportedGrantTypes="IMPLICIT"
        port="8085"
        clientStore-ref="clientStore"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module" />

You may use the JDBC Transport or the Mongo DB transport for database-backed client object stores. Similarly, you may define settings for storing the access tokens and the refresh tokens:


         
      
1
2
3
4
<spring:bean name="tokenStore" class="org.mule.modules.oauth2.provider.token.ObjectStoreTokenStore">
        <spring:property name="refreshTokenObjectStore" ref="refreshTokenObjectStore" />
        <spring:property name="accessTokenObjectStore" ref="accessTokenObjectStore" />
    </spring:bean>

If you do this, you then need to reference these in the oauth2-provider:


         
      
1
2
3
4
5
6
7
8
9
10
<oauth2-provider:config
        name="oauth2ProviderRegister"
        providerName="SampleAPI"
        supportedGrantTypes="IMPLICIT"
        port="8085"
        tokenStore-ref="tokenStore"
        authorizationEndpointPath="sampleapi/api/authorize"
        accessTokenEndpointPath="sampleapi/api/token"
        resourceOwnerSecurityProvider-ref="resourceOwnerSecurityProvider"
        scopes="READ_RESOURCE POST_RESOURCE" doc:name="OAuth provider module" />

Obtaining User Credentials

In some cases, you might want to have access to information about what externally authenticated users are using your API. To obtain this information, you can add an expression component with the following script:


         
      
1
2
3
<expression-component>
    message.outboundProperties.put('X-Authenticated-userid', _muleEvent.session.securityContext.authentication.principal.username)
</expression-component>

The script above stores the username in the mule message as an outbound-property named X-Authenticated-userid. You can modify this code to change the name of the header being created if you wish.

See Also