OAuth 2.0—Creating a Client and Managing Access

Version 9

    A Jive instance supports both Basic and OAuth 2.0 for authentication protocols. When using OAuth 2.0, Jive acts as both the authorization and resource server. While OAuth takes more effort to set up, it allows a third-party service to make API calls securely without the need to pass user credentials for every call and offers better access management through the use of tokens. Jive implements the Authorization Code Grant and the Resource Owner Password Credentials Grant only, as defined by the specification (Implicit Grand & Client Credentials Grant are excluded).

     

     


     

    Introduction

    In order to use OAuth with Jive, we have to register a client with Jive by creating and installing an add-on. Using this gives us a client ID and secret that we can use in one of the two grant methods to receive a Access Token and Refresh Token. This document details OAuth 2.0 processes for Jive, creating a client, and managing token authorization. Requires Jive 7+ and some management features are specifically for Jive Cloud.

     

    Overview

    Shown below is the flow of data and requests during OAuth grants.

    1. A community manager (or someone with the ability to install add-ons) must install a Jive add-on into your community. This add-on contains the redirect (registration) URL that Jive will call.
    2. Jive sends the generated client ID, secret to the registration URL and also a Jive Signature (optional).
      • You can also get the client id & secret manually from the Admin Add-on UI.
    3. You can then verify the authenticity of the source by checking the Jive signature with the Jive Global Registry (optional).
      • Using a Jive Signature will give you system admin access to the community.
    4. Use the client ID and secret to request an access token and refresh token using the Authorization Code Grant or Resource Owner Password Credentials Grant.
    5. If your client ID and secret successfully verify, Jive grants you an access token and a refresh token.
    6. Use that access token to make REST API calls.
    7. When the access token expires, use the refresh token to request a new tokens.
    8. Jive grants you additional tokens.
    9. Make additional REST API calls with the new valid access token.

     


     

    Building an OAuth 2.0 Client

    You can manually create the meta.json and defintion.json packages with the fields needed or use the automated tools to build your add-on as outlined below. To optionally Create a Signed Add-on , you must either create the add-on with either of the two tools below and modifying the definition.json file, or just creating the add-on manually—please see the Manual section on where to place the signature.

     

    Using the Jive OAuth 2.0 Builder

    For those of you who just want to get things running as quickly as possible, we recommend using the Jive OAuth 2.0 Client Builder. Just simply enter a redirect URL that will be called after the add-on is installed (this URL will also receive a payload with the Client ID and Secret). You can also change the default title, description, and image if desired (not required).

    Screen Shot 2015-10-07 at 1.17.56 PM.png

     

    Using the Node.JS Jive-SDK (v 0.1.208+)

    Open you Command Prompt or Terminal and enter the following command to generate an add-on package:

    jive-sdk create oauth2-client --oauthAuthorizeURL="YOUR_REDIRECT_URL"
    

     

    Manually Create Add-on

    There are two critical files in creating the OAuth client—meta.json and definition.json. There are two variations that you can have for the definition file—unsigned or signed (see Creating a Signed Add-on). The meta file needs a UUID, name, description. If you are using a service for registration (see Optional Example Registration Service), you can add the "register_url", "unregister_url", and "service_url". If you are going to have the user grant authorization to the client, you'll need to add a "redirect_url" field; used for Authorization Code Grant. After these files are created, you'll need to zip them with attention to the directory structure and then install the Add-on into your Jive community.

     

    /data/icon-16.png, /data/icon-48.png, /data/icon-128.png (Add-on icons are optional, below are samples)

    sample-icon-16.pngsample-icon-48.png sample-icon-128.png

     

    /definition.json (signed)

    {
         "integrationUser" : {
              "systemAdmin" : true,
              "jiveServiceSignature" : "INSERT_YOUR_SIGNATURE"
         }
    }
    

     

    /definition.json (unsigned)

    {
         "integrationUser" : {
              "systemAdmin" : false
    }
    

     

    /meta.json

    {
         "package_version" : "1.0",
         "id" : "INSERT_A_UUID_FOR_THE_ADD-ON",
         "type" : "client-app",
         "name" : "INSERT_ADD-ON_NAME",
         "description" : "INSERT_A_DESCRIPTION_FOR_THE_ADD-ON",
         "minimum_version" : "0000",
         "icon_16" : "icon-16.png",
         "icon_48" : "icon-48.png",
         "icon_128" : "icon-128.png",
         "service_url" : "OPTIONAL",
         "register_url" : "OPTIONAL",
         "unregister_url" : "OPTIONAL",
         "redirect_url" : "OPTIONAL"
    }
    

    NOTE: The Authorization Code Grant method requires the "redirect_url" parameter and a value.

     


     

    Obtaining (and Validating) Client ID & Secret

    When the add-on is installed, Jive will attempt to call your service to the optional "register_url" entry with a registration payload. We are providing a Node.JS/Express example service in a sub-section below that you can use as your registration service starting point. You can also obtain the Client ID and Secret through the Add-on Admin UI.

     

    Registration Payload

    Sent as a HTTP POST to the URL listed in the optional "register_url" field in the meta.json file. Example below:

    {  
        "clientId": "lh64648h4mwdnucakt52fe08dpnw8u41.i",  
        "code": "8r2a8cxwifo4du7rahq0kppqd5xwemmc.c",  
        "scope": "uri:/api",  
        "tenantId": "bb6360f5-e633-4dcc-bfb4-b357459bf94e-dev",  
        "jiveSignatureURL": "https://market.apps.jivesoftware.com/appsmarket/services/rest/jive/instance/validation/2193ba06-170f-4b81-b9eb-de69073603f8",  
        "clientSecret": "8rpn9srrgv9p42gs4bykkcd51o6vuh0q.s",  
        "jiveSignature": "suKgMCkNJ4n5g4zcNNxdKS7LdnvaMeLdbpWvE40Jc+E=",  
        "jiveUrl": "http://your.jive.community.com",  
        "timestamp": "2015-05-28T20:35:38.358+0000"  
    }  
    

     

    From Add-on Admin UI

    Click your Avatar on the main nav > Manage Add-ons > Gear icon (next to your installed OAuth Client Add-on) > View Client ID and Secret

    add-on_manager.png

     

    Example Registration Service (optional)

    The following Node.js code is a simple example service you could use as a starting point for your service. It listens on the /register and /unregister endpoints, and prints the body of any request to the console.

    var express = require('express');  
      
    var app = express();  
    var port = 8090;  
    var registerEndpoint = 'register';  
    var unregisterEndpoint = 'unregister';  
      
    // Prints the payload to console and then returns a 204 response.  
    function handlePayload(endpoint, req, res) {  
        var body = "";  
        req.on('data', function (chunk) {  
            body += chunk;  
        });  
        req.on('end', function () {  
            console.log('Payload from the '+endpoint+' endpoint:\n' + body);  
            res.writeHead(204);  
            res.end();  
        });  
    }  
      
    // Handle the register request  
    app.post('/'+registerEndpoint+'/', function(req, res) {  
      handlePayload(registerEndpoint, req, res);  
    });  
      
    // Handle the unregister request  
    app.post('/'+unregisterEndpoint+'/', function(req, res) {  
      handlePayload(unregisterEndpoint, req, res);  
    });  
      
    // Listen on the specified port  
    app.listen(port);  
    console.log('Express server started on port ' + port); 
    

     

    Validate Payload Source (optional)

    If you want to ensure that this information came from a valid source, follow these instructions: Ensure Register Calls are Coming from a Genuine Jive Instance

     


     

    Obtaining Access and Refresh Tokens

    There are two methods for getting Tokens from Jive; using the OAuth Authorization Code Grant and Resource Owner Password Credentials Grant. Both methods are implemented as per the OAuth 2.0 specification.

     

    Using Authorization Code Grant

    Once an OAuth 2.0 Client add-on has been installed from the registry or uploaded to the Jive instance, the general flow will be as follows:

    1. The user logs in to the client's web application in a browser.
    2. Client directs the user to the Jive's authorization end-point (typically in a new iframe), which is <jive-url>/oauth2/authorize
    3. Client includes the required parameters client_id=<client_id>&response_type=code and any optional parameters (scope, state or redirect_uri).
    4. If the browser doesn't have a logged in session for Jive, Jive will ask the user to login first.
    5. Jive presents an authorization screen asking the user to allow or deny the authorization grant (scope is not shown to user at this time).
    6. Assuming user allows authorization, Jive will redirect to user back to the redirect_uri (if it was sent to the authorization end-point) or to the redirect_uri provided in the add-on.
    7. A short lived authorization code is attached as a query parameter to the redirect URL along with state parameter if it was provided earlier:

      h ttps://client.application.com/oauth2/redirect?code=<AUTHZ_CODE>
      
    8. Client makes a POST request to the token end-point authorizing the request using client credentials. CURL:
      curl -u '<CLIENT_ID>:<CLIENT_SECRET>' -d 'code=<AUTHZ_CODE>&grant_type=authorization_code&client_id=<CLIENT_ID>' h ttps://<JIVE-URL>/oauth2/token
      
    9. Jive responds with something like:
      {
          "access_token":"qwergqefq5bad5fp03rwjwzzyh3da8vyha92wm6f.t",
          "refresh_token":"79wr2gsl32m8xgwxcxbc027fsjzn5sf0l7wrn3g3.r",
          "token_type":"bearer",
          "expires_in":"172799"
      }
      

     


     

    Using Resource Owner Password Credentials Grant

    Using this grant type requires the client to obtain the username and password from a Jive instance user and then the client makes a request to the Jive instance that the extension is installed. There is an optional parameter that can be sent in the request called "scope" that we implement and enforce as URI based. This scope parameter has a very exact syntax for which types of calls are allowed. For example, if we specify a scope with the value "uri:/api/core/v3" we would only allow v3 API calls (default is "uri:/" which provides access to all calls).

     

    CURL request format:

    curl -u '<CLIENT_ID>:<CLIENT_SECRET>' -d 'grant_type=password&username=<USERNAME>&password=<PASSWORD>' https://<JIVE-URL>/oauth2/token
    

     

    If the client credentials can be authenticated by Jive as valid and the user has access to the client, then Jive will respond with the access and refresh token, e.g.:

    {
         "token_type":"bearer",
         "expires_in":"172799",
         "access_token":"qwergqefq5bad5fp03rwjwzzyh3da8vyha92wm6f.t",
         "refresh_token":"79wr2gsl32m8xgwxcxbc027fsjzn5sf0l7wrn3g3.r"
    }
    

     

    NOTE: If you are using the Jive Developer Sandbox, the "password" grant type (specified in this example) will not work because your sandbox account is federated. You can use the "authorization_code" grant type instead. See Using Authorization Code Grant for more information.

     


     

    Using the Access and Refresh Tokens

    By default, the Access Token is valid for 48 hours from issuance, and that is reflected in the "expires_in" parameter of the payload. A request made with an expired Access Token will result in a 401 response code. The Refresh Token has a default lifespan of 10 years and is used to request a new Access Token once the current one expires.

     

    Make REST API Calls with the Access Token

    You can now use the access token (in the Authorization: Bearer header) to make Jive REST API calls. For example, this call creates a new discussion:

    curl -X POST -i -H 'Authorization: Bearer qwergqefq5bad5fp03rwjwzzyh3da8vyha92wm6f.t'
    -H 'Content-Type: application/json' 'https://your.jive.commmunity.com/api/core/v3/contents'
    -d '{ "type": "discussion", "content": { "type": "text/html", "text":"Starting a discussion"}, "subject": "A new OAUTH discussion"}'
    

     


     

    Request New Access Token with Refresh Token

    In order to replace an expired token, we need to use the Refresh Token, Client ID and Client Secrect. After making a successful request, Jive will respond with a new Access Token and Refresh Token. You can then use the new Access Token to make your REST API calls. Here is the structure for a CURL request:

    curl -u '<CLIENT_ID>:<CLIENT_SECRET>'
    -d 'grant_type=refresh_token&refresh_token=<REFRESH_TOKEN>'
    https://your.jive.community.com/oauth2/token
    

     


     

    OAuth Client Management

    Set Token Expiration Settings

    You can easily change the time to expiration for both the Refresh and Access Token. The defaults for Access Tokens is 48 hours and Refresh Token is 10 years. To get to these settings, you need to click your Avatar on the main nav > Manage Add-ons > Gear Icon > Advance Settings.

    Screen Shot 2015-10-07 at 3.50.35 PM.png


     

    Revoking Permissions

    At any point a user might want to revoke access to a previously granted client or view which applications they may have given access to. There are two ways to revoke an authorization that was granted by a user—through the Jive UI or by performing a REST API call.

     

    Revoke with App Management (UI)

    To get to the management screen, click your Avatar on the main nav > Manage Add-ons > Apps Management. You can revoke access to any specific application that was once granted from that panel and it will revoke both the Access and Refresh Token, requiring the user to have to grant access again using the Authorization Code Grant method.

     


     

    Revoke with a REST API Call

    In order to revoke access through the REST API, we will be using the Jive REST API → Authorization entity  to retrieve a list of authorizations given by a person and then delete. You will first need to know the ID of the user which you can get by using Jive REST API → Person service.

    NOTE: You can only send GET and DELETE requests using the REST API, you cannot modify or grant authorizations.

    GET a List of User Grants

    We send a CURL command with the user ID to get a list of their grants:

    curl -x GET -u USERNAME:PASSWORD "http://YOUR_JIVE_DOMAIN/api/core/v3/admin/people/USER_ID/authorizations/oauth"
    

     

    The response will include a payload in the body that will have the following format, we just need the ID of the grant:

     {
         "id" : "1108",
         "name" : "Jive for iOS",
         "agent" : "",
         "type" : "oauth",
         "created" : "2013-12-10T23:16:49.793+0000",
         "expires" : "2028-12-14T23:16:49.791+0000",
         "appNames" : [ "Jive" ]
    }
    

     

    Delete (revoke) a Single Grant

    Using the ID of the matching named Add-on, we send the following CURL to revoke the Access and Refresh Tokens related to that grant:

    curl -X DELETE -u USERNAME:PASSWORD "http://YOUR_JIVE_DOMAIN/api/core/v3/admin/people/authorizations/oauth/1108"
    

     


     

    References & What's  Next