Using OAuth in your applications

Version 1

    Overview

     

    Because Jive is an opensocial container, Jive applications always support making OAuth requests. A Jive instance is an OAuth client (consumer) rather than an OAuth  server (provider). The Jive Application Framework currently supports OAuth 1.0a and OAuth 2.0 Web Server profile implementations. The Jive container supports the signing specified in  OAuth 1.0a, so your applications can also perform signed fetch, commonly  referred to as two-legged OAuth.

     

    Signed Fetch

     

    As an OpenSocial spec-conforming container, Jive container allows for HTTP/S requests to any external server through the Core Gadget Spec'sgadget.io.makeRequest and osapi.http.* APIs.In certain cases, the server to which an application sends requests may  want to authenticate that the request actually originated from a known  client, in this case, your Jive application. Typically, this external server is the application back-end server, or "home server." The gadget.io.makeRequest and osapi.http.* APIs enable an application developer to specify the need for authorization through an authorization parameter as shown in the following examples.

     

    gadget.io.makeRequest API:

     

     

    ...
    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
    ...
    gadgets.io.makeRequest(url, null, params);

     

     

    osapi.http.* API:


     

    osapi.http.post({
    'href' : 'http://external-server.example.com:9000/perform-verified-action',
    ...
    'authz' : 'signed',
    ...

     


    osml:


     

    <Content view="home"
               href="
    http://external-server.example.com:9000/perform-verified-action"
               authz="signed"
               oauth_service_name="hmac"
               sign_viewer="false"
               refreshInterval="86400"
               xmlns:os="
    http://ns.opensocial.org/2008/markup">

        <os:OwnerRequest key="owner_info" fields="displayName,name,"/>

     


    Both makeRequest and osapi send the request to the Jive server, which attaches a digital signature before forwarding the request to the external server specified in the url or href parameter. When the external server receives this request, it can validate the signature in the request by recreating the signature following the same rules as the signing server and comparing the two signature values. The signing rules for both the Jive server and the verifying external server  are defined by the OAuth 1.0a's signing process which says:

     

    OAuth provides three methods for the client to prove its rightful

    ownership of the credentials: "HMAC-SHA1", "RSA-SHA1", and "PLAINTEXT".

     

    Currently, Jive supports only the HMAC-SHA1 method of signing. (Please provide feedback to the Developer's community if your application requires other methods of signing.) The credentials used to generate the signature string, the oauth consumer key and oauth consumer secret, are established at the time of application registration. It is important to protect these credentials unless your application does not have a need to make signed requests, or in the case of the external activity API where your application's backend server itself is the signing party. Because there is currently no means to re-establish these credentials, it is important to protect them so they can be used in the future.

     

    Two legged OAuth is meant for authorized communication between two parties: in this case, the Jive OpenSocial container (also known as the Jive instance) and the application's home server. Your application can make signed requests to one or more external servers, and it is your responsibility as a developer to make sure all your servers have access to the credentials so they can validate the signature in the request. However, the other party, the Jive OpenSocial container where your application is installed, may cease to exist temporarily or permanently due to license or other issues. Not only that, your application may get installed and re-installed in new Jive OS containers as it gains popularity or also uninstalled from the existing ones. Given this scenario, to make signed fetches possible there are a few choices:

     

    1. Send your application's credentials to each Jive OpenSocial container. However, this is problematic because your application credentials cannot be shared with these containers securely given multiple Jive containers and the container's variable status.
    2. Assign new credentials for each Jive OpenSocial container that installs your application. This approach requires securely conveying the credentials to your application's home server so it can recognize and authorize requests from different Jive instances. This is a complicated approach to the problem, and it also puts an extra burden on the application developer.
    3. Move the burden to a party in the middle. This party can:
      1. Act as a proxy for your application's home server(s) to the various Jive instances
      2. Acts as a representative of all Jive instances to your application home server.

     

    Jive Application Framework has adopted choice 3 above because it addresses issues with the other two choices. The middle party is called the Jive Application Gateway. As a developer, the Gateway provides the ability to validate signatures in requests from your application regardless of which Jive instance it is installed in. Because the Jive instance and the Gateway communicate with a completely different set of credentials, multiple pairs of credentials can be maintained without compromising security. A signed fetch request flow can be illustrated as follows:

     

    oa2.png

     

    Although it always receives signed requests from the Gateway, your application's home server can distinguish requests from multiple Jive instances where your application is installed by looking at the additional OpenSocial parameters sent along with the request. This technique can also be used in cases where your home server doesn't really need to authorize requests, but still needs to keep track of the request origin. These additional OpenSocial parameters include:

     

    • opensocial_owner_id - This value is a composite id of the form <user_id>@<jive_instance_id>. The user_id string is a non-unique opaque id.jive_instance_id is a Jive instance id string - a unique opaque id separated by the @ sign.
    • opensocial_viewer_id - This value uses the same format as opensocial_owner_id. In Jive 5.0, opensocial_owner_id and opensocial_viewer_id will contain the  same value.
    • opensocial_app_url - Your application's URL as seen by the Jive instances.
    • opensocial_app_id - Your application's unique id.

     

    These parameters and standard oauth parameters are always sent as query parameters, regardless of the HTTP method type (HEAD, GET, POST, PUT or DELETE). A sample signed fetch request looks like this:

     

    http:/app-home-server.example.com/signed-fetch?my_app_param=val&oauth_consumer_key=myAppKey&

    oauth_nonce=7sGE00xSfY4PBStICbXyPbIliNymOhu2&oauth_signature_method=HMAC-SHA1&

    oauth_timestamp=1290013827&oauth_version=1.0&opensocial_app_id=my_app_id&

    opensocial_app_url=&opensocial_owner_id=1001@jive_id_N&opensocial_viewer_id=1001@jive_id_N&

    oauth_signature=N7mODAf9OJ1DXQRPisRqGK4DNMo=

     

    Gateway forwards all headers: essential headers such as Accept, Content-Type, Content-Length as well as any custom headers that don't start with X-Jive or X-OAuth.

    Note that if your application's HTTP scheme is https, then communication between Jive and Gateway will also use https.

     

    Here is a list of signature validation code in different languages. A sample Java standalone demo server that uses oauth.net library to validate signatures (oauth-demo-server.tar.gz) is attached  to this document for your reference. It requires maven2 to buil. The package includes a README.txt file that contains build and run command line information.

     

    3-Legged OAuth

     

    Jive OpenSocial container also performs as an OAuth proxy. This functionality enables you to write applications that mash up a wide variety of Jive data with information available from other OAuth providers such as Facebook, Twitter, Google, Yahoo, Gowalla, LinkedIn, Foursquare, and Netflix. Although Jive is an OpenSocial container in the sense that social networking concepts and data are present and accessible through the OpenSocial API specification, in Jive 5.0, the owner and viewer will be the same user. With that said, an OAuth enabled Jive application is similar many ways to an OAuth-enabled gadget in a simple OpenSocial container such as iGoogle. So the OAuth techniques described in this page are quite applicable to Jive. However, there are a few important Jive-specific differences:

     

    1. Jive is not an OAuth provider. This means that a Jive user's private data, stored in a Jive instance, is not accessible outside that instance. There are exceptions to this rule, such as mobile access, but no published API, client credentials or OAuth endpoints are available for external applications to access this data through OAuth.

    2. Jive as an OAuth consumer/client only uses HMAC_SHA1 as a signature method. This means you must register with OAuth services, obtain client credentials (key & secret) and provide them to the Jive application framework before you submit your application for publishing in the Jive Apps Market.

    3. When you write an OpenSocial application that completely conforms to the OpenSocial specification, it is important to test for interoperability. Due to varying degrees of support of different versions of the specification by other containers, your application may not be interoperable out of the box. However, your application works exactly the same way across all Jive instances. Furthermore, you do not have to register and provide oauth client credentials for each of the Jive instances where your application gets installed. You provide credentials one time for each provider that your application uses. Jive Application Framework takes care of securely managing the credentials for you through the Jive Application Gateway.

     

    Adding OAuth (1.0a) service to your application:


    The steps to add a service provider that implements OAuth 1.0a specification are slightly different from OAuth 2.0 Draft 10 implementing service. Though twitter is used as an example to make things easier, the following steps highlight areas relevant to OAuth flow in general. Suppose you want to implement a feature that sends a Twitter update of your activities at Jive based on a certain filter such as time or keyword. You need to:


    1. Obtain write access, so your application can do a Twitter update on behalf of the currently authenticated Jive user using your application.
    2. Use Jive core API to fetch the user's activities.

     

    We will be mainly focusing on #1.

     

    Step 1:

     

    Go to http://dev.twitter.com/apps and register your application. For callback URL provide:

     

    The Jive instance where your app is installed will override this using the oauth_callback OAuth parameter.  Be sure to choose both Read and Write access, since you need write access to update a user's twitter status. Upon successful registration, Twitter will provide you with the api key, OAuth endpoints, consumer key and secret, etc.

     

    Step 2:


    In your application's definition file (gadget XML) add Twitter's request, authorization & access token endpoints under the Module/ModulePrefs/OAuth/Service element.

     

     

    <Module>
      <ModulePrefs title="...">
         ...
         <Require feature="jive-core-v2" />
         <OAuth>
             <Service name="twitter">
               <Access url="http://api.twitter.com/oauth/access_token" method="POST" />
               <Request url="http://api.twitter.com/oauth/request_token" method="POST" />
               <Authorization url="http://api.twitter.com/oauth/authorize" />
             </Service>
         </OAuth>

     

     

    Step 3:

     

    Assuming you will be using makeRequest, add the following in your POST request to http://api.twitter.com/1/statuses/update.json:

     

     

    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.OAUTH;

     

     

    This request initiates the OAuth flow for the first time. After the user grants access to your application going through the OAuth dance, Jive stores the resulting access token. Subsequent login sessions will use this token to perform the update. The access token is generally valid until expiration, until the user uninstalls your application, or until the user goes to Twitter and explicitly removes authorization to your application.

     

    The first-time response will be a JSON content, an object with 3 properties 1. oauthApprovalUrl 2. data 3. errorText.

     

    If it is oauthApprovalUrl,  then open a popup window with location set to the approval URL so the user can login to twitter and either approve or deny access to your application. gadgets.oauth.Popup is made available for to you for this purpose. The function also calls you back when the popup is opened/closed. You may use the open callback, for example to show appropriate message to the user such as "Awaiting authorization..."  and make your Twitter API call again in the close callback. If the user had granted access to your application, this time around the update will succeed since Jive would use the access token to sign Update API call. If the user had denied approval, the response will again contain the oauthApprovalUrl.

     

    new gadgets.oauth.Popup(

                  response.oauthApprovalUrl,

                  "height=350, width=550",

                  function() { // do something }, /* onOpen callback */

                  function() { //do something } /* onClose callback */

    );

     

    Step 4:

     

    Now add your app using command line tools and then visit http://developers.jivesoftware.com/devcenter and provide twitter's key and secret for your app.

    #

    Adding OAuth (2.0 draft 10) service to your application:

     

    Facebook, Foursquare, and SFDC are some of the OAuth 2.0 services out there. Currently, the OpenSocial specification doesn't support OAuth 2.0 clients. However, you can still use Module/ModulePrefs/OAuth/Service element to define an OAuth 2.0 service. There are two areas where OAuth 2.0's web server profile usage differs from OAuth 1.0a. We will look at these two areas and how they differ. But the rest of OAuth 1.0a server addition holds good for OAuth 2.0's web server client profile.

     

    1. Since there is no request token concept in OAuth 2.0, there really is no need for the Request element in the OAuth Service definition. Since Request is a required part of OAuth Service, the following is what the application framework expects:

     

    <OAuth>
         <Service name="facebook">
            <Request url="https://gateway.jivesoftware.com/oauth2" method="GET" param_location="uri-query"/>
            <Access url="https://graph.facebook.com/oauth/access_token" method="GET" param_location="uri-query"/>
            <!--                                                                                                                                                                                               
                Facebook uses a URL format to indicate which permissions an app is requesting                                                                                                                  
                access to. The "offline_access" permission is recommended so that the Jive Application                                                                                                         
                Gateway does not need to refresh the oAuth token as frequently. Full details can be found                                                                                                   
                at
    http://developers.facebook.com/docs/authentication/                                                                                                                                         
                and
    http://developers.facebook.com/docs/authentication/permissions                                                                                                                             
             -->

            <Authorization url="https://graph.facebook.com/oauth/authorize?scope=read_stream,offline_access"/>
         </Service>
    </OAuth>

     

    2. In OAuth 2.0 requires a static redirection URI. When registering your application with the OAuth 2.0 resource server, be sure to provide the following as that redirection URI:

     

    http://gateway.jivesoftware.com/gateway/oauth2/redirect

     

    Both http & https schemes are supported. Sample Twitter and Facebook applications are attached to this document to help you quickly understand and use OAuth services in your application.

     

    3-Legged OAuth with Google

     

    Unlike many oauth providers Google requires that the site that uses oauth be registered with Google, otherwise, Google will show a warning message asking your application user to not approve access to their protected data with Google. Google will provide you consumer key and consumer secret only after a successful registration. Since your application would run on different Jive instances, the domains that, you as an appliation developer won't be the owner of, the only alternative is to register with Google a domain that you own and that will be familiar to users of your application. If you do not own a domain, you can sign-up for one for free with Google's app engine in order to be able to register your domain. If you do so, be sure to use your appname for subdomain eg. acme-inc-jiveapp.appspot.com so your app user could identify who is asking for approval.