Skip navigation

Craig McClanahan's Blog

May 2012 Previous month Next month

1.  Introduction


This document provides a high level architectural view of how web services are implemented in Jive, with a particular focus on how authentication and authorization are used to control who can make what kinds of requests.  We start with reviewing the design principles on which Jive web services are designed, then examine the overall architecture of a Jive instance, and the internal layering inside the Jive web application, to observe where the various constraints and restrictions are enforced.


2.  Jive Web Service APIs are RESTful


Jive's web services are designed and implemented in the REST architectural style, which has several key characteristics:

  • Individual objects (resources) are each assigned their own URI, and represented in JSON.
  • The HTTP verb used on a particular request determines what action should be taken on the resource at the contacted URI.  A typical pattern is to use these verbs as follows:
    • GET - Retrieve a current representation of the resource identified by this URI.
    • PUT - Update the resource identified by this URI, based on information in the representation submitted in this request.
    • DELETE - Delete the resource identified by this URI.
    • POST - Create a new resource "contained" by the resource identified by this URI, based on information in the representation submitted in this request.  Then, return a response that includes the URI assigned to the new resource.
  • The response from the server will include an HTTP status code that reports on the success or failure of the request.  Common status codes that are returned include:
    • 200 (OK) -- The request succeeded, and the response body includes the requested resource representation(s).
    • 201 (CREATED) -- A new object was successfully created, and the response includes a Location header whose value is the URI of the newly created resource.
    • 204 (NO CONTENT) -- The request succeeded, but no response body was included.
    • 400 (BAD REQUEST) -- The server recognized the verb and URI included in the request, but one or more input fields failed validation rules in the business logic.  An error message describing the problem will be included in the response.
    • 401 (UNAUTHORIZED) -- The action that was requested requires authentication, but the request did not include any valid credentials.
    • 403 (FORBIDDEN) -- The server recognized the caller (based on the submitted credentials), as well as the action that was requested, but entitlement rules in the business logic dictate that the caller is not allowed to perform the requested action.
    • 404 (NOT FOUND) -- The request URI does not identify a valid resource.
    • 405 (METHOD NOT ALLOWED) -- Returned when a client attempts to perform an operation on a specific URI, with a verb that is not supported by that URI.
  • Returned resources will include resource links -- a named set of URIs, along with the set of verbs that the server supports at this URI, for this requesting user (permission differences mean that different users will see different verbs for the same URIs).  Given these resource links, a client application can:
    • Determine what this particular URI is for.  The name of each resource link, and the behavior of each possible verb, are documented both in the static API documentation, and (from Jive Core API V3 on) in the online metadata that a client can access programatically.
      • Example -- the resource links that accompany a Jive place (blog, group, project, or space) includes a URI named activity (Core API V3 or later) which, if you perform a GET against it, will return the latest activity stream entries that have occurred in this place.
      • Example -- the resource links that accompany a Jive content object includes a URI named likes that includes some combination of the following verbs (Core API V3 or later):
        • GET -- will retrieve the people who have liked this content object.
        • POST -- will register a like for this object from the requesting user (only available where the requesting user is allowed to view the object, has not liked it already, and is not the author of this object).
        • DELETE -- will remove a like for this object (only available if the requesting user has previously liked this object).
    • Perform an action against this URI without ever looking at it the URI itself, or trying to compose a URI programmatically.  This vastly improves the robustness of client applications as the server application evolves, because the server will always keep the URIs it generates up to date with the current implementation.
    • Predict ahead of time whether or not accessing this URI with a particular verb (using the same authenticated user as the one who retrieved this resource) will be allowed or not.
      • Example -- if comments on a content object are closed, or the requesting user is not allowed to comment on it, the comments resource link will not have a POST verb present.  This can be reflected in a client application UI by not enabling a comment button or link.
  • For GET requests that returns lists of objects, the server will also return next and previous URIs to retrieve the next or previous page of results that match the criteria on this request (the previous URI will not be present on the first page).


Due to the use of this architectural style, Jive (and its clients) experience many benefits:

  • It becomes possible for the client browser, or intermediate proxy servers, to cache results -- but have the caches immediately updated when a PUT or DELETE operation alters an existing resource at this URI.
  • A single URI per resource reduces the conceptual complexity of the overall API, by avoiding the need to create URIs that are artificially different solely to identify different operations on the same resource.
  • The presence of resource link URIs means that the number of actual URIs a client application must be aware of is dramatically reduced -- most of the time, the client is simply treating resource link URIs as a opaque value and following the link returned in a previous resource.
  • Although the primary topic of this document is REST clients, the resource links are also utilized in the JavaScript API available to Jive Apps to automatically generate corresponding helper methods on the JavaScript objects corresponding to each resource.


These web services are used by several types of clients:

  • The Web UI of the Jive application itself uses XMLHttpRequest calls to retrieve data and perform operations.
  • Jive Apps running within the overall Jive application can use the APIs to interact with Jive places and content (typically using a JavaScript layer on top of the REST APIs).
  • Various Jive cloud services, such as Jive Anywhere and Jive Mobile, interact with Jive instances through this API.
  • External application clients can interact with a Jive instance for use cases like content migration or data synchronization.


3.  Overall Architecture


An installed Jive instance has several components, as shown in the following diagram:




Details of the firewall and load balancer components will vary based on whether this Jive instance is on premise or in the cloud, but the basic roles of each element are the same:


Firewall -- Prevent malicious access (detect potentially problematic usage, whitelist or blacklist IP addresses, etc.), manage traffic, and perform content filtering.

Load Balancer -- Distribute incoming traffic between web nodes.  The number of web node instances is based on the overall expected request volume.

Web Node -- A configured VM (or, in some cases, bare metal machine) that runs the Apache and Tomcat elements described below.    No users have access to these VMs at the operating system level -- only administrative accounts that manage the services are allowed.  The software stack running on each web node is identical.

  • For clarity, other nodes running other internal services, such as the database, are not shown.

Apache HTTPD Server -- Apache is used for several purposes:

  • Serve static resources (HTML pages, CSS stylesheets, JavaScript files, and UI page templates).  Because WebDAV is not configured, only HEAD and GET requests for static resources are supported.  PUT, POST, and DELETE commands will have no effect on these URIs.
  • Proxy requests for web services on specific URI paths (such as "/api/core/v2" for the Jive Core API version2 ) to the Jive application running inside Tomcat.
    • The proxied information includes the request URI, the HTTP verb, any included HTTP headers, and the request body (if any).
    • The information returned from the Jive application includes an HTTP status, any generated HTTP headers, and the response body (if any).
  • Maintain access and error logs for later analysis and reporting.


Tomcat Application Server -- Tomcat is used to host the Jive web application that contains the functional logic for the web services, and all of the actions supported in the Jive UI.  We examine the architecture of the Jive application in the next section.

4.  Web Application Architecture


The internal structure of the Jive web application can be considered as a series of layers with specific responsibilities, as depicted here:




Each layer of the internal stack have responsibilities described in the following subsections:


4.1 Authorization Filter


The first layer of the Jive web application that processes incoming requests is the Authorization Filter.  It examines the incoming request for valid credentials (delegating to whatever identity provider is in use for this particular Jive instance, returning a an HTTP 401 (UNAUTHORIZED) status if the credentials are invalid.


Request handling for anonymous requests depends on whether the Jive instance has been configured to support anonymous users in the web UI:

  • If anonymous UI users are not allowed, anonymous web service requests are rejected with a 401 (UNAUTHORIZED) status.
  • If anonymous UI users are allowed, so are anonymous web service requests.


Note that, even if anonymous web service requests are allowed, not all such requests will succeed.  The Web Service Mapper layer (next section) has the responsibility to enforce authenticated requests based on the business rules that define the Jive application's overall behavior.


4.2 Web Service Mapper


The Jive web application uses a web service stack based on the Java API for RESTful Web Services standard, which uses code annotations to map an incoming request URI and verb combination to the corresponding functional logic that performs the requested action.  A simplified example of such annotations on a service class looks like this:


public class DocumentService ... {


    public void deleteDocument(@PathParam("id") long id) {




    public DocumentEntity getDocument(@PathParam("id") long id)




    public DocumentEntity updateDocument(@PathParam("id") long id,
                                         @QueryParam("minorEdit") @DefaultValue("false")
                                             boolean minorEdit,
                                         DocumentEntity document) {






So, if the Jive application were to receive a request like this:


PUT {jiveURL}/api/core/v2/documents/1234


it will be mapped to the updateDocument() method in the DocumentService class as follows:

  • The /api/core/v2 part of the URI is configured external to the DocumentService class (this is the prefix for all Jive Core API V2 web service calls).
  • The /documents part of the URI is matched to the @Path declaration on this service class (if this part had been /discussions instead, a class named DiscussionService would have been selected).
    • If this portion of the URI does not match any configured service class, an HTTP 404 (NOT FOUND) will be returned.
  • The /1234 part of the URI potentially matches three different service methods that are annotated with the /{id} pattern.
    • If this portion of the URI did not match the path template on any method in this service class, an HTTP 404 (NOT FOUND) will be returned.
  • The verb from the request (PUT in this case) is matched against the @PUT annotation on the updateDocument() class, and that method is selected.
    • If there are one or more methods whose URI matches the path template, but none of them have the correct verb annotation, an HTTP 405 (METHOD NOT ALLOWED) will be returned.
  • The @RequiresAuthentication annotation (a Jive extension to the JAX-RS standard) tells the web service mapper that this request is not allowed for anonymous requests.  In general, we will see such requirements on any request that modifies the state of the system (pretty much every method annotated with DELETE, POST, or PUT), and on some GET methods that do not make sense to support for anonymous users (such as "retrieve the requesting user's activity" when we do not know who the requesting user is).
  • The updateDocument() method itself is passed the id of the document to be updated (from the URI), a query parameter indicating that this is a minor edit (defaults to false if not present), and a Java object representing the request body that contains the new content for this document.
  • The updateDocument() method implementation will utilize the lower layers of the Jive implementation, starting with the Jive Proxy layer, as described in the next section.


4.2.1 What About PUT and DELETE?  Aren't They Dangerous?


Verbs like PUT and DELETE have been part of Hypertext Transfer Protocol -- HTTP/1.1 since it was formalized in 1999.  However, early browsers only implemented support for GET and POST, so application developers were not able to fully employ the REST architectural style described above.  Later on, the availability of XMLHttpRequest, and it's ability to use all of the available HTTP verbs, opened up the design possibilities again so that applications could gain all of the benefits.


In the mean time, other technologies such as WebDAV were developed that did utilize these verbs (as well as others), for application-to-server integration scenarios.  Unfortunately, some early web server implementations that supported WebDAV shipped with a default configuration that allowed PUT and DELETE requests to modify or delete resource files on the server.  This led some IT departments to consider the methods themselves to be dangerous, and to configure their network environments to disallow them.


As we have seen from the above description, in a Jive environment, Apache is configured without WebDAV, so modification or removal of static resources via Apache is not possible.  The verbs are passed on to the web service mapper, and (as we have seen) are used to select the appropriate processing method for each particular request.


The interesting thing to note is that there is nothing intrinsically dangerous about the actual verbs themselves -- if the server developer maps the wrong verb to the wrong business logic, the system is broken whether the actual verb was PUT or POST.  On the other hand, if the mapping is coded correctly (as in the example above), the delete or update request is appropriately processed.  We still don't know whether the request will actually be allowed -- that's up to the next layer -- but there is no security improvement to be had from configuring network equipment to disallow PUT and DELETE.  Indeed, that would essentially break the entire Jive application, as well as every other RESTful web service application installed behind such a network configuration.


4.3 Jive Proxy


All business logic inside of Jive is actually encapsulated in a Jive Manager (next layer), but that manager is wrapped in a proxy layer that performs entitlement checks that verifies that the requesting user has the right to perform the requested action.  If the entitlement check passes, control will be delegated to the Jive Manager layer to perform the actual request.  If the entitlement check fails, an HTTP 403 (FORBIDDEN) will be returned, even if the verb and URI in the request were correct.


Examples of requests that will return a 403 because of entitlement check failures:

  • Attempt to access a secret social group (or content inside that social group) that the requesting user is not a member of.
  • Attempt to read a content object whose visibility has been restricted (for example, while a document is being developed it might be shared with a small number of reviewers until completion, when it could then be made available to a broader audience).
  • Attempt to modify or delete a content object for which the requesting user only has view permissions.


4.4 Jive Manager


By the time a request reaches a Jive Manager, we know that the original request was well formed, and that the calling user has the right to perform the requested action.  Therefore, no further entitlement checks are required.


The actual business logic for a particular request is encapsulated in this layer.  Additionally, for performance reasons, many Jive manager implementations support caching of the relevant database data at this tier.  If a Jive Manager needs to collaborate with other Jive Managers to accomplish a particular task, they can do so -- but a Jive Manager will never talk to any Data Access Object (DAO) layer object except it's own.


4.5 Jive DAO


The Data Access Object layer performs SQL requests against the underlying database.  In all cases, JDBC prepared statements are used, which avoids any potential for SQL injection attacks.


5. Summary


As we have seen above, the architecture of the Jive application (and the environment it runs in) is comprehensively designed to safely and securely perform only authorized actions, whether those actions are requested from a Jive user via the Web UI, a Jive App running within Jive, various Jive cloud services such as Jive Mobile, or an external client application using the REST API endpoints.  Suitable controls are in place to:

  • Ignore any potentially malicious HTTP request targeted at static resources on the web servier.
  • Correctly select the appropriate business logic based on the HTTP verb and the request URI that were specified.
  • Reject anonymous requests for a web service action that requires authentication.
  • Validate the entitlements of the requesting user to perform the requested action.
  • Avoid any potential for SQL injection attacks by the universal use of JDBC prepared statements.