Introduction
An API Builder project provides different types of security mechanisms to authenticate requests. Typically, you want to restrict which client applications have access to your APIs, and you want the client to prove it has permission to access your API Builder application's APIs.
By default, a new API Builder project uses HTTP basic authentication, where the client must pass
the API key in the Authorization header for each request. A new API Builder project contains two generated API keys, apikey_development
and apikey_production
, located in the conf/default.js
file. The apikey_development
key contains the key used to test your project locally, while apikey_production
is used to make requests to your project when it is published. You may
change the values for these keys but make sure you generate a sufficiently
unique value and do not share these keys with other API projects as they
control access to your APIs. These keys should only be used by one API Builder project.
To change the authentication mechanism, open the conf/default.js
file and change the APIKeyAuthType
key to one of the following:
none
: No authentication. The client does not need any authentication to access these APIs. In this case, all client requests are accepted without any security. Use the valuenone
for the keyAPIKeyAuthType
.basic
: Use HTTP basic authentication (default). The client uses the HTTPAuthorization
header to send an encoded version of the API Key using the HTTP Basic Authentication standard. The username part is the value of the API Key and the password part should be blank (empty string). Use the valuebasic
for the keyAPIKeyAuthType
.apikey
: Use HTTP header authentication. The client sets the HTTPAPIKey
header to the value of the API Key. In this scenario, the server must only support HTTPS only endpoints so the key is not passed in plain text. Use the valueapikey
for the keyAPIKeyAuthType
.ldap
(since API Builder (Arrow) 1.2.x): Use the LDAP plugin for authentication. You must also set theldap
key to an object containing settings for the LDAP configuration. The client uses the HTTPAuthorization
header to send an encoded version of the API Key using the HTTP Basic Authentication standard. The username and password will be sent to the configured LDAP server for authentication. Use the valueldap
for the keyAPIKeyAuthType
.- plugin: Use a custom or third-party authentication mechanism. Using the
plugin strategy, you can extend the authentication to use any third-party
or custom API authentication. To build your own plugin, set the value
plugin
for the keyAPIKeyAuthType
to use this strategy, then set the keyAPIKeyAuthPlugin
to the location of your plugin. The location can be a file path (relative to the current work directory of your server project directory) or the name of the module package available in the standardnode_modules
location.
The following describes the authentication mechanisms.
HTTP basic authentication
In HTTP basic access authentication, the client needs to send a username
and password, sent as a base64-encoded string "<username>:<password>
", in the Authorization header of the HTTP request, for example:
GET api /model HTTP /1 .0 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
For API Builder applications, the username is the API key and the password field is left blank. For a Titanium application, you can construct the header and request as follows:
var xhr = Ti.Network.createHTTPClient({ onload: function onLoad() { alert( "Loaded: " + this .status + ": " + this .responseText); }, onerror: function onError() { alert( "Error: " + this .status + ": " + this .responseText); } }); xhr.open( "GET" , REQUEST_URL); var authstr = 'Basic ' + Ti.Utils.base64encode(API_KEY + ':' ); xhr.setRequestHeader( "Authorization" , authstr); xhr.send(); |
HTTP header authentication
In HTTP header authentication, the client sends the API key in a custom APIKey header. The server must only support HTTPS requests, so the key is not sent as plain text (unencrypted).
var xhr = Ti.Network.createHTTPClient({ onload: function onLoad() { alert( "Loaded: " + this .status + ": " + this .responseText); }, onerror: function onError() { alert( "Error: " + this .status + ": " + this .responseText); } }); xhr.open( "GET" , REQUEST_URL); xhr.setRequestHeader( "APIKey" , API_KEY); xhr.send(); |
LDAP
Starting with API Builder 1.2.x, you may use the LDAP plugin to authenticate requests. The client application will need to use HTTP basic authentication to send the username and password in the HTTP authorization header to the API Builder application.
To use the plugin, you need to pass your LDAP settings to the ldap
object in the conf/default.js
file. Define the following key-value pairs:
Key
|
Optional
|
Description
|
---|---|---|
url | No | LDAP URL to connect to. |
adminDn |
No | Distinguished name (DN) of the user that is allowed to connect to the LDAP database and read user and group data. |
adminPassword |
Yes | Password for the directory administrator. |
searchBase |
No | The base DN to search for users. |
searchFilter |
No | LDAP search filter to find a user. |
groupSearchBase |
Yes | The base DN to search for groups. |
groupSearchFilter |
Yes | LDAP search filter to find a group. |
cache |
Yes | Set to true to cache up to 100 sessions for five minutes. The default is false. |
tlsOptions |
Yes | Additional options to pass to the Node.js tls.connect() callback. |
Example:
module.exports = { ... APIKeyAuthType: 'ldap' , ldap: { url: 'ldap://ldap.foo.com:389' , adminDn: 'cn=read-only-admin,dc=example,dc=com' , adminPassword: 'password' , searchBase: 'dc=example,dc=com' , searchFilter: '(uid={{username}})' }, ... } |
Custom authentication
To use a custom authentication mechanism, you need to create a CommonJS
module that exposes a plugin class and implements the following methods.
All methods are optional, but to validate requests, you need to implement
the validateRequest
method, either the synchronous version or asynchronous version.
Method Signature
|
Description
|
---|---|
Plugin(server) |
Constructor. Passed the server instance. The passed server instance has not registered any models or connectors and has not been started. |
Plugin.prototype.matchURL(request): Boolean |
Determines if the URL should be authenticated by the plugin. Return true if the plugin should handle the validation else return false. |
Plugin.prototype.validateRequest(request, response): Boolean |
Validates the request synchronously. Return a Boolean value indicating if the request passed validation (true) or not (false). Do not implement if you implemented the asynchronous version of this method. |
Plugin.prototype.validateRequest(request, response, callback): void |
Validates the request asynchronously. Pass the callback an Error as its first argument (or null if successful) and a Boolean indicating if validation was a successful or not as its second argument. Do not implement if you implemented the synchronous version of this method. |
Plugin.prototype.applyCredentialsForTest(options): void |
Used by the API Doc tab in the API Builder Console to allow the plugin to apply any authentication headers to the request before it is made.
The options object is the same options object passed to the request library. |
Plugin.prototype.applyRequestsForTest(response, body): Object |
Used by the API Doc tab in the API Builder Console to allow the plugin to modify the authentication response headers, body, etc. |
Plugin.prototype.getSwaggerSecurity |
Used by Swagger generation to describe the Swagger Definitions Object and the Swagger Requirement Object authentication mechanism. |
In the conf/default.js
file, set the APIKeyAuthPlugin
key to the location of the plugin file or to the name of the flow-node
module if you specify it as a dependency in the package.json
file.
For example, if your client applications send a custom header, called X-Secret
, for each request and you want to check the value sent with the request
against one stored in your configuration file, you can use the plugin below.
module.exports = { ... APIKeyAuthType: 'plugin' , APIKeyAuthPlugin: './lib/plugin.js' , secret: 'secret' , ... } |
To test the plugin, add the -H 'X-Secret: secret'
command-line option to the cURL request.
$ curl "http://127.0.0.1:8080/api/foo" { "id" : "com.appcelerator.api.unauthorized" , "message" : "Unauthorized" , "success" : false } { "success" : true , "request-id" : "0d2141f7-57ea-4c78-82cf-b6fa9497c16a" , "foo" : "bar" } |