com.atlassian.confluence.content.render.xhtml.migration.exceptions.UnknownMacroMigrationException: The macro 'next_previous_links' is unknown.

Token API

Users need access tokens to invoke APIs subscribed under an application. Access tokens are passed in the HTTP header when invoking APIs. The API Manager provides a Token API that you can use to generate and renew user and application access tokens. The response of the Token API is a JSON message. You extract the token from the JSON and pass it with an HTTP Authorization header to access the API.

Let's take a look at how to generate/renew access tokens and authorize them. WSO2 API Manager supports the four most common authorization grant types and you can also define additional types such as SAML.

Generating access tokens with user credentials (password grant type)

You can obtain an access token by providing the resource owner's username and password as an authorization grant. It requires the base64 encoded string of the consumer-key:consumer-secret combination. You need to meet the following prerequisites before using the Token API to generate a token.

Prerequisites

  • A valid user account in the API Store. You can self sign up if it is enabled by an admin.
  • A valid consumer key and consumer secret pair. Initially, these keys must be generated through the management console by clicking the Generate link on My Subscriptions page. You can find more details in Invoke an API using the Integrated REST Client.
  • A running API Gateway instance (typically an API Manager instance should be running). For instructions on API Gateway, see Components.  
  • If you have multiple Carbon servers (such as API Manager and WSO2 Application Server) running on the same computer, you must change the port offset to avoid port conflicts. Setting the port offset causes API Manager to run on a different port from the default.

  • If the Key Manager is running on a different server from the API Gateway instance, change the host and port of the endpoints of the default APIs that are in <APIM_HOME>/repository/deployment/server/synapse-configs/default/api to the correct address of the Key Manager.

Invoking the Token API to generate tokens   

  1. Combine the consumer key and consumer secret keys in the format consumer-key:consumer-secret and encode the combined string using base64. Encoding to base64 can be done using the URL: http://base64encode.org.
    Here's an example consumer key and secret combination : wU62DjlyDBnq87GlBwplfqvmAbAa:ksdSdoefDDP7wpaElfqvmjDue.
  2. Access the Token API by using a REST client such as the WSO2 REST Client or Curl, with the following parameters.
    • Assuming that both the client and the API Gateway are run on the same server, the token API url is https://localhost:8243/token
    • payload - "grant_type=password&username=<username>&password=<password>&scope=<scope>". Replace the <username> and <password> values as appropriate.
       <scope> is optional, you can leave it off if necessary. And if you have multiple scopes, add them all seperated by a space.
    • headers - Authorization: Basic <base64 encoded string>, Content-Type: application/x-www-form-urlencoded. Replace the <base64 encoded string> as appropriate.          

    For example, use the following cURL command to access the Token API. It generates two tokens as an access token and a refresh token. You can use the refresh token at the time a token is renewed .

    curl -k -d "grant_type=password&username=<username>&password=<password>" -H "Authorization: Basic SVpzSWk2SERiQjVlOFZLZFpBblVpX2ZaM2Y4YTpHbTBiSjZvV1Y4ZkM1T1FMTGxDNmpzbEFDVzhh" -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token
    CuRL command with Scopes
    curl -k -d "grant_type=password&username=<username>&password=<password>&scope=<scope1> <scope2>" -H "Authorization: Basic SVpzSWk2SERiQjVlOFZLZFpBblVpX2ZaM2Y4YTpHbTBiSjZvV1Y4ZkM1T1FMTGxDNmpzbEFDVzhh" -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token

    Tip: If you define a scope for an API's resource, the API can only be accessed through a token that is issued for the scope of the said resource. For example, if you define a scope named 'update' and issue one token for the scopes 'read' and 'update', the token is allowed to access the resource. However, if you issue the token for the scope named 'read', the request to the API will be blocked.

    The Token API endpoint is specified in <APIM_HOME>/repository/deployment/server/synapse-configs/default/api/_TokenAPI_.xml file. When running the server on a different port from the default (i.e., 9443), or if your Key Manager is running on a different machine from your API Gateway, you must update the endpoint inside the _TokenAPI_.xml file as described in the prerequisites.

    User access tokens have a fixed expiration time, which is set to 60 minutes by default. Before deploying the API manager to users, extend the default expiration time by editing the <AccessTokenDefaultValidityPeriod> tag in <PRODUCT_HOME>/repository/conf/identity.xml.

    When a user access token expires, the user can try regenerating the token as explained in the Renew user tokens section.

Instead of using the Token API, you can generate access tokens from the API Store UI. See Invoke an API using the Integrated REST Client for information.

Generating access tokens with authorization code (authorization code grant type)

Instead of requesting authorization directly from the resource owner (resource owner's credentials), in this grant type, the client directs the resource owner to an authorization server. The authorization server works as an intermediary between the client and resource owner to issues an authorization code, authenticate the resource owner and obtain authorization. As this is a redirection-based flow, the client must be capable of interacting with the resource owner's user-agent (typically a Web browser) and receiving incoming requests (via redirection) from the authorization server.

The client initiates the flow by directing the resource owner's user-agent to the authorization endpoint (you can use the /authorize endpoint for the authorization code grant type of OAuth 2.0). It includes the client identifier, response_type, requested scope, and a redirection URI to which the authorization server sends the user-agent back after granting access. The authorization server authenticates the resource owner (via the user-agent) and establishes whether the resource owner granted or denied the client's access request. Assuming the resource owner grants access, the authorization server then redirects the user-agent back to the client using the redirection URI provided earlier. The redirection URI includes an authorization code.

The client then requests an access token from the authorization server's /token endpoint by including the authorization code received in the previous step. When making the request, the client authenticates with the authorization server. It then includes the redirection URI used to obtain the authorization code for verification. The authorization server authenticates the client, validates the authorization code, and ensures that the redirection URI matches the URI used to redirect the client from the /authorize endpoint in the previous response. If valid, the authorization server responds back with an access token and, optionally, a refresh token.

Invoking the Token API to generate tokens

Assuming that both the client and the API Gateway are run on the same server, the Authorization API URL is https://localhost:8243/authorize.

  • query component: response_type=code&client_id=<consumer_key>&scope=PRODUCTION&redirect_uri=<application_callback_url>
  • headers: Content-Type: application/x-www-form-urlencoded

For example, the client directs the user-agent to make the following HTTP request using TLS.

GET
/authorize?response_type=code&client_id=wU62DjlyDBnq87GlBwplfqvmAbAa&scope=PRODUCTION&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
HTTP/1.1 
Host: server.example.com 
Content-Type:
application/x-www-form-urlencoded 

The authorization server redirects the user-agent by sending the following HTTP response:

HTTP/1.1 302 Found 
Location:
https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA

Now the client makes the following HTTP request using TLS to the /token endpoint.

POST /token HTTP/1.1 
Host: server.example.com 
Authorization: Basic
SVpzSWk2SERiQjVlOFZLZFpBblVpX2ZaM2Y4YTpHbTBiSjZvV1Y4ZkM1T1FMTGxDNmpzbEFDVzhh
Content-Type:
application/x-www-form-urlencoded 
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

The /token endpoint responds in the same way like in password grant type.

Note that if you are using a separate server for authentication (e.g., a distributed API Manager setup or an instance of WSO2 Identity Server as the authentication server), be sure to give the full URL of the authentication server in <APIM_HOME>/repository/conf/security/application-authenticators.xml file. The default configuration has a relative path, which works in a standalone API Manager setup:

<Authenticators>
   <Authenticator name="BasicAuthenticator" disabled="false" factor="1">
      <Status value="10" loginPage="/authenticationendpoint/login.do" />
   </Authenticator>
</Authenticators>

Generating access tokens with NT Lan Manager (NTLM grant type)

NTLM is the successor of the authentication protocol in Microsoft LAN Manager (LANMAN), an older Microsoft product, and attempts to provide backwards compatibility with LANMAN. You can obtain an access token to your API in an API Manager instance running on Windows by providing a valid NTLM token as an authorization grant. The steps are given below:

Invoking the Token API to generate tokens

  1. Get a valid consumer key and consumer secret pair. Initially, you generate these keys through the API Store by clicking the Generate button on the My Subscriptions page.
  2. Combine the consumer key and consumer secret keys in the format consumer-key:consumer-secret and encode the combined string using base64 (http://base64encode.org). In order to generate an access token with NTLM, you must have an NTLM token. 

  3. Generate an NTLM token by running the sample provided in the <APIM_HOME>/samples/NTLMGrantClient directory. See the Readme.txt in the same folder for instructions.

  4. Invoke the token API in the following manner to get an access token. 
    The value of the  windows_token in the following command is the NTLM token that you generated in the previous step.

    curl -k -d "grant_type=iwa:ntlm&windows_token=<give the NTLM token you got in step 3>" -H 
    "Authorization: Basic <give the string you got in step2>" -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token

Exchanging SAML2 bearer tokens with OAuth2 (SAML extension grant type)

SAML 2.0 is an XML-based protocol. It uses security tokens containing assertions to pass information about an end-user between a SAML authority and a SAML consumer. A SAML authority is an identity provider (IDP) and a SAML consumer is a service provider (SP).

Enterprise applications use SAML2 to engage a third-party identity provider to grant access to systems that are only authenticated against the enterprise application. These enterprise applications might need to consume OAuth-protected resources through APIs, after validating them against an OAuth2.0 authentication server. However, an enterprise application that already has a working SAML2.0 based SSO infrastructure between itself and the IDP prefers to use the existing trust relationship, even if the OAuth authorization server is entirely different from the IDP. The SAML2 Bearer Assertion Profile for OAuth2.0 leverages this existing trust relationship. It presents the SAML2.0 token to the authorization server and exchanges it to an OAuth2.0 access token.

WSO2 API Manager provides SAML2 Bearer Assertion Profile Support with the OAuth 2.0 feature. WSO2 Identity Server  (version 4.5.0 onwards) or any other SAML2 Identity provider can act as an identity service provider for the systems enabled with SSO. WSO2 API Manager acts as the OAuth authorization server. This way, an enterprise application can exchange the SAML2.0 bearer token that it retrieves when authenticating against an IDP (e.g., WSO2 Identity Server) with an OAuth2.0 access token from an OAuth authorization server (e.g., WSO2 API Manager). It can then use the OAuth2 token in API invocations.

The diagram below depicts this scenario:

   
The scenarios of the above diagram are explained below:

Scenario [1]: User initiates login call to an enterprise application .

Scenario [2]:

  • As the application is a SAML SP, it redirects the user to the SAML2.0 IDP to log in.
  • The user provides credentials at the IDP and is redirected back to the SP with a SAML2.0 token signed by the IDP.
  • The SP verifies the token and logs the user to the application.
  • The SAML 2.0 token is stored in the user's session by the SP.  

Scenario [3]:

  • The enterprise application (SP) wants to access an OAuth2 protected API resource through WSO2 API Manager.
  • The application makes a request to the API Manager to exchange the SAML2 bearer token for an OAuth2.0 access token.
  • The API Manager validates the assertion and returns the access token.

Scenario [4]: User does API invocations through the API Manager by setting it as an Authorization header with the returned OAuth2 access token.

Before you configure the token exchange, do the following:

  • Register to a valid user account in the API Store.
  • Get a valid consumer key and consumer secret. Initially, these keys must be generated through the management console by clicking the Generate link on My Subscriptions page. For more information, see Invoke an API using the Integrated REST Client. 
  • Set up a running API Gateway instance.
  • If you have multiple WSO2 servers (such as WSO2 API Manager and WSO2 Application Server) running on the same machine, change the port offset and update the token API's endpoint accordingly. Additionally, if the key manager is on a different server from the API Gateway, update the token API endpoint to use the correct host and port. For more information, see this prerequisite in the previous section.

Configuring the token exchange

We use WSO2 Identity Server 5.0.0 as the IDP to get a SAML token and the API Manager as the OAuth server.

  1. Log in to the API Manager's management console (https://localhost:9443/carbon) using admin/admin credentials and select Add under Identity Providers menu in the Main menu. 
  2. Provide the following values to configure the IDP:
    • Under Basic Information 
      • Identity Provider Name: Enter a unique name for IDP
      • Identity Provider Public CertificateExport the public certificate of WSO2 IS and import it here.
        Alternatively, you can create a self-signed certificate and then export it as a .cer file using the following commands: 

        keytool -genkey -alias wookie -keyalg RSA -keystore wookieKeystore.jks -keysize 4096
        keytool -v -export -file keystore1.cer -keystore keystore1.jks -alias keystore1

         

      • Alias: Give the name of the alias if the Identity Provider identifies this token endpoint by an alias. E.g., https://localhost:9443/oauth2/token
    • Under Federated Authenticators -> SAML2 Web SSO Configuration

      • Enable SAML2 Web SSO: true

      • Identity Provider Entity Id: The SAML2 issuer name specified when generating the assertion token, which contains the unique identifier of the IDP. You give this name when configuring the SP.

      • Service Provider Entity IdIssuer name given when configuring the SP
      • SSO URL: Enter the IDP's SAML2 Web SSO URL value. E.g., https://localhost:9444/samlsso/ if you have offset the default port, which is 9443.
     
  3. Log in to the management console of the Identity Server and select Add under Service Providers menu in the Main menu.
  4. Choose to edit the service provider that you just registered and select SAML2 Web SSO Configuration.
     
  5. Provide the following values to configure the SP:

     Let's see how to get a signed SAML2 token (encoded assertion value) when authenticating against a SAML2 IDP. With the authentication request, you pass attributes such as the SAML2 issuer name, token endpoint and the restricted audience. In this guide, we use a command-line client program to create the SAML2 assertion.
  6. Get the SAML token using the client JAR.
    An example command is given below. TestSP is the name of the issuer. 

    java -jar SAML2AssertionCreator.jar TestSP admin https://localhost:9443/oauth2/token https://localhost:9443/oauth2/token/home/dinusha/nothing/WSO2/API-Manager/saml-oauth/wso2is-5.0.0/rhbepository/resources/security/wso2carbon.jks wso2carbon wso2carbon wso2carbon

    You receive the consumer key and consumer secret.

  7. Retrieve the encoded assertion string.
    Use the following format in a base64-url encoder (e.g., https://www.base64encode.org/) to encode the consumer key and consumer secret that you received in step 6

    <consumer-key>:<consumer-secret>

     


     

  8. Retrieve the OAuth Access token.
    Use the base64-url Encoded Assertion String that you derived in step 7 as the value for
    <ASSERTION_PROVIDED_BY_CLIENT> in the following command.

    An example command is given below.

    curl -k -d "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&assertion=<ASSERTION_PROVIDED_BY_CLIENT>&scope=PRODUCTION" -H "Authorization: Basic <ASSERTION_PROVIDED_BY_CLIENT>, Content-Type: application/x-www-form-urlencoded" https://localhost:9443/oauth2/token

Invoking Token API to generate tokens   

Follow the steps below to invoke the token API to generate access tokens from SAML2 assertions.

  1. Combine the consumer key and consumer secret keys as consumer-key:consumer-secret. Encode the combined string using base64 ( http://base64encode.org). Here's an example consumer key and secret combination: wU62DjlyDBnq87GlBwplfqvmAbAa:ksdSdoefDDP7wpaElfqvmjDue.
  2. Access the token API using a REST client such as the WSO2 REST Client or Curl. The parameters are explained below:

    • Assuming that both the client and the API Gateway run on the same server, the Token API URL is https://localhost:8243/token.
    • Create a SAML2 Assertion.
      You can use the command line client program from here. Extract the ZIP file, change directory into the extracted folder and execute the following command in the command line. You will get SAML2 Assertion XML String and base64-URL Encoded Assertion XML String. Use base64-URL Encoded Assertion XML String as SAML2_Encoded Assertion_Token.

      java -jar SAML2AssertionCreator.jar <Identity_Provider_Entity_Id> admin https://localhost:9443/oauth2/token https://localhost:9443/oauth2/token <Identity_Provider_JKS_file> <Identity_Provider_JKS_password> <Identity_Provider_certificate_alias>

      The arguments are as follows:

      • The saml:Issuer (a unique identifier of the identity provider) value
      • The saml:Subject -> saml:NameId value
      • The value of saml:Subject -> saml:SubjectConfirmation -> saml:SubjectConfirmationData.Recipient
      • The fourth argument can take multiple values separated by commas. They are added to the saml:AudienceRestriction element of the token. Each value is added as a saml:Audience element within saml:AudienceRestriction.
      • Pointer to the Java Key Store (JKS) file to be used for credentials
      • The JKS password
      • The alias of the public certificate
      • The password of the private key that is used for signing

      This commend returns a SAML2 assertion XML string and a base64-URL encoded assertion XML string. 

    • Access the Token API using a REST client such as Curl. For example, the following Curl command generates an access token and a refresh token. You can use the refresh token at the time a token is renewed.

      curl -k -d "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&assertion=<base64-URL_encoded_assertion>&scope=PRODUCTION" -H "Authorization: Basic <base64_encoded_consumer-key:consumer-secret>" -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token

The Token API endpoint is specified in <APIM_HOME>/repository/deployment/server/synapse-configs/default/api/_TokenAPI_.xml file. When running the server on a different port from the default (i.e., 9443), or if your Key Manager is running on a different server from your API Gateway, you must update the endpoint inside the _TokenAPI_.xml file as described here.

Renewing access tokens

After an access token is generated, sometimes you might have to renew the old token due to expiration or security concerns. You can renew an access token using a refresh token, by issuing a REST call to the Token API with the following parameters. 

  • Assuming that both the client and the API Gateway are run on the same server, the Token API URL is https://localhost:8243/token.
  • payload - "grant_type=refresh_token&refresh_token=<retoken>". Replace the <retoken> value with the refresh token generated in the previous section .
  • headers - Authorization :Basic <base64 encoded string>, Content-Type: application/x-www-form-urlencoded. Replace <base64 encoded string> as appropriate.          

For example, the following cURL command can be used to access the Token API.

curl -k -d "grant_type=refresh_token&refresh_token=<retoken>" -H "Authorization: Basic SVpzSWk2SERiQjVlOFZLZFpBblVpX2ZaM2Y4YTpHbTBiSjZvV1Y4ZkM1T1FMTGxDNmpzbEFDVzhh" -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token

The above REST message grants you a renewed access token along with a refresh token, which you can use the next time you renew the access token. A refresh token can be used only once. At the moment, a refresh token never expires, but we will provide a way to configure an expiration time in a future release.

Revoking access tokens

After issuing an access token, a user or an admin can revoke it in case of theft or a security violation. You can do this by calling Revoke API using a utility like cURL. The Revoke API's endpoint URL is http://localhost:8280/revoke.

Parameters required to invoke this API are as follows:

  • The token to be revoked
  • Consumer key and consumer secret must be encoded using Base64 algorithm.

For example, curl -k -d "token=<ACCESS_TOKEN_TO_BE_REVOKED>" -H "Authorization: Basic Base64Encoded(Consumer key:consumer secret)" http://localhost:8280/revoke.

When the API Gateway cache is enabled (it is enabled by default), even after revoking a token, it might still be available in the cache to consumers until the cache expires in approximately 15 minutes. You can clear the cache manually by restarting the server.

Configuring the token expiration time

Configuring the token expiration time

User access tokens have a fixed expiration time, which is set to 60 minutes by default. Before deploying the API Manager to users, extend the default expiration time by editing the <AccessTokenDefaultValidityPeriod> element in <PRODUCT_HOME>/repository/conf/identity.xml.

Also take the time stamp skew into account when configuring the expiration time. The time stamp skew is used to manage small time gaps in the system clocks of different servers. For example, let's say you have two Key Managers and you generate a token from the first one and authenticate with the other. If the second server's clock runs 300 seconds ahead, you can configure a 300s time stamp skew in the first server. When the first Key Manager generates a token (e.g., with the default life span, which is 3600 seconds), the time stamp skew is deducted from the token's life span. The new life span is 3300 seconds and the first server calls the second server after 3200 seconds.

You configure the time stamp skew using the <TimestampSkew> element in <PRODUCT_HOME>/repository/conf/identity.xml

Ideally, the time stamp skew should not be larger than the token's life span. Also, note that when the API Gateway cache is enabled (it is enabled by default), even after a token expires, it will still be available in the cache for consumers until the cache expires in approximately 15 minutes.

com.atlassian.confluence.content.render.xhtml.migration.exceptions.UnknownMacroMigrationException: The macro 'next_previous_links2' is unknown.