Showing posts with label Fellowship One. Show all posts
Showing posts with label Fellowship One. Show all posts

Wednesday, February 25, 2009

RESTful Thoughts - OAUTH implementation for the F1 RESTful API Part 1



We took some time with this implementation and really did some soul searching on Authentication / Authorization mechanisms for the new Fellowship One API. The past few APIs that we've released used credential based authentication ( + signed keys for Payment Gateway) which was appropriate considering the intended usage.

With the RESTful API we know that churches, 3rd parties, vendors, volunteers, and the like will be consuming the API's secure resources - so we chose OAUTH.

The OAUTH features enable all of those consumers to create web sites or applications (consumers) that can access resources available via Fellowship One (Service Provider) securely, and without having to store or gather user credentials.

The benefits of our implementation of OAUTH are:
  • Both the church and user will be able to protect / authorize access to their resources
  • Resources will only be available to applications that both the church and users of that church has access to (configurable)
  • The Consumer will never have access to login information or credentials - so the login is totally owned by the service provider
All requests for resources (excluding tokens and login) must have a Consumer Key, Access Token, and signature.

Roles of our implementation of OAUTH are:
  • Service Provider: Fellowship One RESTful API - A web application (API) that allows access via OAuth.
  • Consumer: 3rd party / church / Individual - A website or application that uses OAuth to access the Service Provider on behalf of the User.
  • User: Portal User, User, Weblink User - An individual who has an account with the Service Provider.
OAUTH Parameter information (from the protocol documents):
  • Consumer Key: A value used by the Consumer to identify itself to the Service Provider.
  • Consumer Secret: A secret used by the Consumer to establish ownership of the Consumer Key.
  • Request Token: A value used by the Consumer to obtain authorization from the User, and exchanged for an Access Token.
  • Access Token: A value 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.
  • Token Secret: A secret used by the Consumer to establish ownership of a given Token.
  • OAuth Protocol Parameters: Parameters with names beginning with oauth_.
Brief overview of the F1 OAUTH process (assuming all valid credentials and authority):
  • The Consumer application will use a consumer key and secret to sign all URIs so that the F1 API will be able to verify the consumers identity and credentials.
  • The Consumer application first requests a "Request Token" to use when the Users access the login pages -> The Service provider grants the request token.
  • The Consumer application will direct the User to the Service Provider to obtain User Authorization
  • The Service Provider will obtain authorization from the User and direct the User back to the Consumer
  • The Consumer application will then request an Access Token -> The Service provider grants the request token and marks the "Content-Location" header with a URI to the User information.
  • The Consumer application will use the Access Token to access Protected Resources
The process defined above requires accessing the following URIs:

Request token URI:
http://{churchcode}.{domain}/{version}/Tokens/RequestToken [POST]

Login URIs:
Portal Users http://{churchcode}.{domain}/{version}/PortalUser/Login [GET]
Weblink Users http://{churchcode}.{domain}/{version}/WeblinkUser/Login [GET]
Groups Users http://{churchcode}.{domain}/{version}/User/Login [GET]

Access Token URI:
http://{churchcode}.{domain}/{version}/Tokens/AccessToken [POST]

Monday, February 2, 2009

RESTful Thoughts - Planned HTTP Headers for the upcoming RESTful API

Here is the HTTP Header map for the upcoming Fellowship One RESTful API. Please comment / ask questions / make suggestions.

Just like the response codes, many decisions made for this map came from RFC2616, Fielding's dissertation, and analysis of several dozen RESTful or REST "like" APIs currently on the programmable web.


Request Headers

Accept : type/subtype

Example - Accept : application/xml (Available types and sub types: application/xml, application/json)

Notes - Defaults to application/xml if one is not passed in, and when a user sends application/* the resulting content sub type will be XML. Multiple types/sub types can be sent in but as per the specification the first match in degree of specificity will be the first used.
i.e. if user sends in: application/*, application/xml, */* the order would be as follows:
1) application/xml
2) application/*
3) */*

If an invalid value is passed in via Accept header the response will result in a 415 Unsupported Media Type


Accept-Charset : charset

Example - Accept-Charset: utf-8

Notes - Accept-Charset will not be used and will always default to utf-8


Accept-Encoding : encoding

Example - Accept-Encoding : deflate, compress, gzip

Notes - If none is sent in then the API will default to no compression.
If an invalid value is passed in via Accept-Encoding header the response will result in a 406 Not acceptable


Authorization : credentials

Example - Authorization : Oauth realm=http://api.f1.com

Notes - This is where the OAUTH credentials will go


Date : HTTP-date

Example - Date: Thu, 29 Jan 2009 15:28:25 GMT

Notes - Optional, most commonly passed in with PUTs and POSTs


User-Agent : product/comment

Example - User-Agent : MyChurchSite/v123.x

Notes - Used to identify the HTTP library or client library that was used to consume the API


Response Headers

Allow : method

Example - Allow: GET, HEAD, PUT

Notes - An Allow header field MUST be present in a 405 (Method Not Allowed) response.


Content-Encoding : content-coding

Example - Content-Encoding : gzip

Notes - This will tell the client what type of compression was used on the resource


Content-Length : DIGIT

Example - Content-Length : 1254

Notes - Sent back with each request. Will possibly be available via HEAD requests


Content-Location : absoluteURI | relativeURI

Example - Content-Location : http://api.f1.com/API/People/22114944

Notes - Sent back with each GET request


Content-Type : media-type

Example - Content-Type : application/xml, utf-8

Notes - Details the type of content being returned to the client


Date : HTTP-date

Example - Date: Thu, 29 Jan 2009 15:28:25 GMT

Notes - Will be returned with every response, possibly excluding responses returning status codes of 500


Location : absoluteURI

Example - Location: http://api.f1.com/API/People/22114944

Notes - Applies to 201 and 301 only


WWW-Authenticate : challenge

Example - WWW-Authenticate : Oauth realm: http://api.f1.com

Notes - The URI will change per environment, per version

Notes on caching
All headers having to do with caching are still being implemented.

This HTTP header map is subject to change, however, in the current build of the API these rules exist as defined.

Wednesday, January 28, 2009

RESTful Thoughts - Planned response status codes for the upcoming RESTful API

In the interest of honoring standards here is the response status code map for the upcoming Fellowship One RESTful API. Please comment / ask questions / make suggestions.

Many decisions made for this map came from RFC2616, Fielding's dissertation, and analysis of several dozen RESTful or REST "like" APIs currently on the programmable web.


200 - ok (GETs, PUTs, and DELETEs)

Entity body - The resource

Example - GET People/1

201 - Resource created (POST)

Response Header - Location will contain the canonical URI

Entity body - the new resource

Example - POST People

301 - Moved Permanently

Response Header - Location will contain the new permanent canonical URI

Entity body - will be empty

Example - GET People/1 has been merged and no longer exists the new URI is People/1

400 - Bad Request: There is an error on the client side.

Response Header - No modification

Entity body - Send back a message on why the request was bad

Example - Malformed XML fails to serialize eon the server

401 - Unauthorized

Response Header - WWW-Authenticate : OAUTH and the challenge or required parameter

Entity body - Optionally, a doc describing the failure

Example - missing OAUTH credentials

403 - Forbidden - Failed authorization

Response Header - No modification

Entity body - explanation of why authorization failed

Example - OAUTH credentials were good, however, the token used for the request was not valid or user associated with the token does not have rights to the resource

404 - Not Found: When a client requests a URI that does not map to a resource on the server

Response Header - No modification

Entity body - will be empty

Example - GET People/1 does not exist, optionally a 410 may be used (see below)

405 - Method not allowed

Response Header - Allow: GET, POST - list the HTTP methods the resource supports

Entity body - will be empty

Example - POST People/1/Status <- an attempt to create a status when only GET is available

409 - Conflict: Client tried to put the servers resource in an impossible or inconsistent state

Response Header - Allow: GET, POST - list the HTTP methods the resource supports

Entity body - will be empty

Example - POST People/1/Status <- an attempt to create a status when only GET is available

410 - Gone: server knew there used to be a resource but it's gone now

Response Header - No modification

Entity body - explanation of conflicts

Example - PUT People/1 modifying "Weblink" credentials for People/1 that are already used by People/2

415 - Unsupported Media Type

Response Header - Code detailed supported media types for the given resource

Entity body - will be empty

Example - Resource only supports XML and JSON, but the client sends application/atom+xm

500 - Internal Server Error

Response Header - No modification

Entity body - will be empty

Example - The server encountered an unexpected condition which prevented it from fulfilling the request.



This response status code map is subject to change, however, in the current build of the API these rules exist as defined above.