Was this helpful?

OAuth 1.0a defines a standard protocol that enables app users to authorize apps to consume APIs on their behalf, without requiring app users to disclose their passwords to the app in the process. Apigee Edge enables you to protect APIs in a way that ensures that an app uses has authorized the app to consume an API. Edge also provides policy-based functionality for configuring the endpoints that app developers can use to obtain access tokens.

Once you have configured OAuth policies on your API, apps must obtain access tokens to consume them. To do so, the app must exchange a 'request token' for the access token.. Rather than relying on a single password as the master key for every app that accesses an API, OAuth uses this token to provide “delegated authentication” between APIs and apps. The resource owner can issue access tokens with restricted scope and limited lifetime, and revoke them independently.

A fully functioning sample proxy that demonstrates 3-legged OAuth 1.0a is available in the API Platform samples on Github.

Configuring an OAuth 1.0a policy

Apigee Edge provides an OAuth 1.0a policy type that enables you to authorize apps with OAuth 1.0a. The OAuthV1 policy type is responsible for generating request tokens, generating access tokens, and verifying access tokens based on the OAuth 1.0a specification.

Generating a request token

A request token is used by a consumer app to obtain authorization from the app end user, and is then presented to the 'token endpoint' to be exchanged for an access token. A request token is generated from a valid consumer key. Here are examples of the simple and comprehensive forms for generating request tokens.

Simple form

<OAuthV1 name="{policy_name}">
  <Operation>GenerateRequestToken</Operation>
</OAuthV1>

Comprehensive form

<OAuthV1 name="{policy_name}">
  <Operation>GenerateRequestToken</Operation>
    <GenerateResponse enabled="true">
    <Format>FORM_PARAM or XML</Format>
    </GenerateResponse>
    <GenerateErrorResponse enabled="true">
      <Format>formparam or xml</Format>
      <Realm>http://oauth.apigee.com/oauth/1/</Realm>
    </GenerateErrorResponse>
</OAuthV1>

The policy enforces the following OAuth semantics:

  • The consumer key is valid.
  • The signature is valid.

A successful request returns the following responses:

  • Generates a request token and its attributes in the flow oauth_token, oauth_token_secret, oauth_callback_confirmed, oauth_response
  • Also makes a consumer token and its attributes available in the flow oauth_consumer_key, oauth_consumer_secret

On failure, a request returns the appropriate response status code with an error message.

Generating an access token

An access token is used by the consumer to gain access to the protected resources on behalf of the user, instead of using the user’s service provider credentials. An access token is created with a valid key, request token, and verifier combination. Here are examples of the simple and comprehensive forms for generating access tokens.

Simple form

<OAuthV1 name="{policy_name}">
   <Operation>GenerateAccessToken</Operation>
</OAuthV1>

Comprehensive form

<OAuthV1 name="{policy_name}">
  <Operation>GenerateAccessToken</Operation>
  <GenerateResponse enabled="true">
    <Format>formparam or xml</Format>
  </GenerateResponse>
  <GenerateErrorResponse enabled="true">
    <Format>FORM_PARAM or XML</Format>
    <Realm>http://oauth.apigee.com/oauth/1/</Realm>
  </GenerateErrorResponse>
</OAuthV1>

The policy enforces the following OAuth semantics:

  • The consumer key is valid.
  • The request token is valid.
  • The verifier is valid.
  • The signature is valid.

A successful request returns the following responses:

  • Generates an access token and its attributes in the flow oauth_token, oauth_token_secret, oauth_response
  • Also makes a consumer token and its attributes available in the flow oauth_consumer_key, oauth_consumer_secret

On failure, a request returns the appropriate response status code with an error message.

Associating a token verification code with a request token

The following policy associates a token verification code with a request token. To receive an access token, both a verification code and a request token are required. 

To use this policy, a verification code must be generated as a separate step outside of Apigee Edge. The verifier value must be a unique, random string.

The verification code fits into the basic OAuth flow as follows. After an app user's credentials are authenticated by a service provider, the service provider must inform the consumer app that the credentials were accepted (that the request token can be exchanged for an access token) and the service provider must also send a verification code. The verification code ensures that the user granting access to the service is the same user who is asking the app to complete the process. Finally, the app asks the provider for an access token. This request requires that both the request token and verification code be provided. For detailed information on this process, see the OAuth 1.0a specification

Comprehensive form

<OAuthV1 name="{policy-name}">
    <Operation>GenerateVerifier</Operation>
    <RequestToken ref="request.header.requesttoken"/>
    <AppUserId ref="request.header.appuserid"/>
    <VerifierCode ref="request.header.verifiercode"/>
    <GenerateResponse enabled="true">
       <Format>FORM_PARAM or XML</Format>
    </GenerateResponse>
​    <Attributes>
       <Attribute name="ver-attr1">ver-attr1</Attribute> 
       <Attribute name="ver-attr2" ref="request.header.ver-attr2"></Attribute> 
       <Attribute name="ver-attr3" display="false">ver-attr3</Attribute> 
    </Attributes>
</OAuthV1>

Parameters

Parameter Description
RequestToken (Required) Specifies the request token with which to associate the verifier. 
AppUserId (Required) Specifies the ID of the application user.
VerifierCode (Required) Specifies the verifier code. This code must be generated outside of Apigee as a separate step. 
Attributes (Optional) Allows you to pass arbitrary values to the access token. If the request token and the verifier have the same attribute name, the verifer value takes precedence. See also "Customizing access tokens" later in this topic.


When this policy executes, the following flow variables are populated:

  • Request Token:  oauthtoken.{policy_name}.oauth_token
  • Verifier Code: authtoken.{policy_name}.verifier_code
  • App User Id: oauthtoken.{policy_name}.app_user_id

Sample response

If GenerateReponse is enabled, then the verifier is returned in the response along with the other attributes.

<response>
    <oauth_parameter name="issued_at"><![CDATA[1389014375368]]></oauth_parameter>
    <oauth_parameter name="expires_at"><![CDATA[1389016175368]]></oauth_parameter>
    <oauth_parameter name="application_name"><![CDATA[f24b582d-701f-4cbd-a1e0-2fc0e77003]]></oauth_parameter>
    <oauth_parameter name="app_user_id"><![CDATA[someappuserid]]></oauth_parameter>
    <oauth_parameter name="organization_id"><![CDATA[0]]></oauth_parameter>
    <oauth_parameter name="oauth_token"><![CDATA[HVEUg3Tb9tM8yMWZAARDcSbgeHp5]]></oauth_parameter>
    <oauth_parameter name="ver-attr1"><![CDATA[ver-attr1]]></oauth_parameter>
    <oauth_parameter name="oauth_verifier"><![CDATA[verifiercode2]]></oauth_parameter>
    <oauth_parameter name="verifier_code"><![CDATA[verifiercode2]]></oauth_parameter>
</response>
 

Verifying an access token

Here are examples of the simple and comprehensive forms for verifying access tokens.

Simple form

<OAuthV1 name="{policy_name}">
  <Operation>VerifyAccessToken</Operation>
</OAuthV1>

Comprehensive form

<OAuthV1 name="{policy_name}">
  <Operation>VerifyAccessToken</Operation>
  <GenerateErrorResponse enabled="true">
    <Format>FORM_PARAM or XML</Format>
    <Realm>http://oauth.apigee.com/oauth/1/</Realm>
  </GenerateErrorResponse>
</OAuthV1>

The policy enforces the following OAuth semantics:

  • The consumer key is valid.
  • The access token is valid.
  • The signature is valid.

A successful validation returns the following responses:

  • Makes an access token and its attributes available in the flow oauth_token, oauth_token_secret, oauth_response
  • Also makes a consumer token and its attributes available in the flow oauth_consumer_key, oauth_consumer_secret

If the request fails verification, the server responds with the appropriate response status code with an error message.

Customizing access tokens

Custom attributes can be optionally included in access, refresh, and verifier tokens.

<Attributes> 
  <Attribute name=”attr_name1” ref=”flow.variable” display="true|false">value1</Attribute>
  <Attribute name=”attr_name2” ref=”flow.variable” display="true|false">value2</Attribute>
</Attributes>

Where display is set to true, custom attributes are returned in the response , where they may be viewable by the app end user.

Where display is set to false, custom attributes are stored in the data store, but are not returned in the response message.

For example, to add the User-Agent associated with the request to an access token:

<OAuthV1 name="GenerateAccessToken">
  <Operation>GenerateAccessToken
  </Operation>
  <ExpiresIn>1000</ExpiresIn>
  <GenerateResponse />
  <SupportedGrantTypes>
    <GrantType>client_credentials</GrantType>
  </SupportedGrantTypes>
  <GrantType>request.queryparam.grant_type</GrantType>
  <Attributes> 
    <Attribute name=”user-agent” ref=”request.header.user-agent” display="false"></Attribute>
  </Attributes>
</OAuthV1>

Policy-specific variables

The OAuthV1 and GetOAuthV1Info Policy types set the following variables when they execute.

GenerateRequestToken operation

  • oauth_token
  • oauth_token_secret
  • oauth_callback_confirmed
  • oauth_response
  • oauth_consumer_key
  • oauth_consumer_secret

GenerateAccessToken operation

  • oauth_token
  • oauth_token_secret
  • oauth_response
  • oauth_consumer_key
  • oauth_consumer_secret

VerifyAccessToken operation

  • oauth_token
  • oauth_token_secret
  • oauth_response
  • oauth_consumer_key
  • oauth_consumer_secret

GetOAuthV1Info

  • oauth_consumer_key
  • oauth_consumer_secret

Policy-specific error codes

The default format for error codes returned by Policies is:

{
  "code" : " {ErrorCode} ",
  "message" : " {Error message} ",
  "contexts" : [ ]
}

The OAuthV1 Policy type defines the following error codes:

Error Code Message
AppKeyNotResolved Could not resolve the app key with variable {0}
ConsumerKeyNotResolved Could not resolve the consumer key with variable {0}
RequestTokenNotResolved Could not resolve the request token with the variable {0}
AccessTokenNotResolved Could not resolve the access token with the variable {0}
ResponseGenerationError Error while generating response : {0}
UnableToDetermineOperation Unable to determine an operation for stepDefinition {0}
UnableToResolveOAuthConfig Unable to resolve the OAuth configuration for {0}
AtLeastOneParamRequired At least one of AccessToken, RequestToken or ConsumerKey must be specified in stepDefinition {0}
SpecifyValueOrRefReqToken Specify Request Token as value or ref in stepDefinition {0}
SpecifyValueOrRefAccToken Specify Access Token as value or ref in stepDefinition {0}
SpecifyValueOrRefConKey Specify Consumer Key as value or ref in stepDefinition {0}
SpecifyValueOrRefAppKey Specify App Key as value or ref in stepDefinition {0}
ExpiresInNotApplicableForOperation ExpiresIn element is not valid for operation {0}
InvalidValueForExpiresIn Invalid value for ExpiresIn element for operation {0}
FailedToFetchApiProduct Failed to fetch api product for key {0}
InvalidTokenType Valid token types : {0}, Invalid toke type {1} in stepDefinition {2}
TokenValueRequired Token value is required in stepDefinition {0}
FailedToResolveRealm Failed to resolve realm {0}

Policy schema

Each policy type is defined by an XML schema (.xsd). For reference, policy schemas are available on GitHub.

Add new comment

Provide your email address if you wish to be contacted offline about your comment.
We will not display your email address as part of your comment.

We'd love your feedback and perspective! Please be as specific as possible.
Type the characters you see in this picture. (verify using audio)

Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.