Home > Help center > API > Athentication and Authorizations

Athentication and Authorizations

OAuth2

OAuth2 is an authentication framework used worldwide; for instance Facebook , Github, and Twitter use this protocol to authenticate their APIs. Before introducing the Billia OAuth2 functionalities, let's briefly look at the core concepts of this authentication system.

In the OAuth2 specification (RFC 6749), we have the following definitions:

  • Resource Owner: the User
  • Resource Server: the API
  • Authorization Server: often the same as the API server
  • Client: the Third-Party Application

In Billia, the Resource Server and the Authorization Server are delivered from the same API server.

The OAuth2 protocol is actually a framework for authorization. From the abstract of RFC 6749 we can read:

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.

The use cases covered by the OAuth2 framework are:

  • Web-server applications
  • Browser-based applications
  • Mobile apps
  • Username and password access
  • Application access

In all these use cases, the goal of the OAuth2 protocol is to exchange a token between the Client and the Resource Server. This token is used to authenticate all the API calls using the Authorization HTTP header. Below is reported an example of the Bearer token (RFC 7650 ), the most used token type of OAuth2:

Authorization: Bearer RsT5OjbzRn430zqMLgV3Ia

Security considerations

The OAuth2 protocol does not guarantee confidentiality and integrity of communications. That means you must protect HTTP communications using an additional layer. One possible solution is the usage of SSL/TLS (HTTPS) to encrypt the communication channel from the client to the server.

The first version of OAuth (OAuth1) supported an authentication mechanism based on the HMAC algorithm to guarantee confidentiality and integrity; OAuth2 does not (although a Draft proposal exists to support MAC tokens). The lack of message hashing is the primary concern raised regarding the security of OAuth2, and the one most developers complain about (e.g. this blog post by Eran Hammer, the ex-lead of the OAuth specifications).

In a nutshell, always use HTTPS for OAuth2, as it's the only way to guarantee message confidentiality and integrity with this protocol!

Client access

This use case is to fetch "public" resources, with infomration about, which client/application is requesting this resource. Note: you can not fetch client related data with client_credentials secret.

POST /oauth HTTP/1.1
Accept: application/json
Content-Type: application/json

{
    "client_id": "client_id",
    "client_secret": "client_secret",
    "grant_type": "client_credentials"
}

The response will be something like:

{
    "access_token": "48c2bf00c6dd2c8add231717cec6324b90ba0422",
    "expires_in": 3600,
    "token_type": "Bearer",
    "scope": null
}

Username and password access

This use case can be used to authenticate an API with user based grants (also known as a password grant). The typical scenario includes a Login web page with username and password that is used to authenticate against a first-party API. Password grant is only appropriate for trusted clients. If you build your own website as a client of your API, then this is a great way to handle logging in.

The authentication mechanism is just 1 step (see diagram below).

The client application sends a POST to the OAuth2 server with the username and password values. The OAuth2 server responds with the token access as part of a JSON payload.

You can use the password grant in two ways: with confidential (trusted) clients, or public clients.

POST /oauth HTTP/1.1
Accept: application/json
Content-Type: application/json

{
    "grant_type": "password",
    "client_id": "client_id",
    "client_secret": "client_secret",
    "username": "testuser",
    "password": "testpass"
}

Public Clients

If we are using a public client (by default, this is true when no secret is associated with the client) you can omit the client_secret value; additionally, you will now pass the client_id in the request body. In our example database the testclient2 client_id has an empty client_secret.

POST /oauth HTTP/1.1
Accept: application/json
Content-Type: application/json

{
    "grant_type": "password",
    "username": "testuser",
    "password": "testpass",
    "client_id": "testclient2"
}

The response will be something like:

{
    "access_token": "c258cf1e088f891d397c2f7345769e609d507aea",
    "expires_in": 3600,
    "token_type": "Bearer",
    "scope": null,
    "refresh_token": "f07cc3409d09efc83845d63f8aa223b8661b93ff"
}

Application access

This use case can be used to authenticate against applications, mosty likely in machine to machine scenarios. The OAuth2 grant type for this use case is called client_credentials. The usage is similar to the public client password access reported above; the application sends a POST request to the OAuth2 server, passing both the client_id and the client_secret in the body. The server replies with the token if the client credentials are valid.

Refresh OAuth2 token

The OAuth2 protocol gives you the possibility to refresh the access token, generating a new one with a new lifetime. This action can be performed using the refresh_token that the OAuth2 server provides in the response during the authentication step.

In Billia, you can refresh the access token with a POST to the OAuth2 server endpoint. In the example SQLite database, we can perform a refresh token using the following command:

POST /oauth HTTP/1.1
Accept: application/json
Content-Type: application/json

{
    "grant_type": "refresh_token",
    "refresh_token": "<the refresh_token>",
    "client_id": "testclient",
    "client_secret": "testpass"
}

The response will be something like:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "access_token": "470d9f3c6b0371ff2a88d0c554cbee9cad495e8d",
    "expires_in": 3600,
    "scope": null,
    "token_type": "Bearer"
}

You can also refresh a token from a trusted client, specifying only the client_id and the refresh_token fields.

Revoke OAuth2 token

Recently, the IETF published RFC 7009, detailing OAuth2 token revocation. Billia doesn't yet support token revocation. However, it is still possible to revoke specific access tokens by removing the value from the database. For instance, if you are using the PDO adapter, all the tokens are stored in the oauth_access_tokens table; if you want to revoke a token you can delete it from the table, with a SQL query:

DELETE FROM oauth_access_tokens WHERE access_token="<token to remove>";

Multiple grant types

For OAuth2 adapters that support grant types, most will allow you to add multiple grant_type's to a client by providing them as space-separated values.

Always consult the documentation for a given adapter to verify the format.

IP Protection

OAuth server support IP validation of the customer's request. The IP of the customer is send to the backend via custom header: X-User-IP-Address. The ip should be forwarded from the webserver ftom the front panels to the backend API.

If the request is not properly authorised (requested from a wrong IP), the API will return:

{
    "_info": {
        "ip": "192.168.13.5"
    },
    "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
    "title": "Forbidden",
    "status": 403,
    "detail": "This resource is IP protected. Please use network, whitelisted to access this software!"
}

The system supports authorisation to IPv4 or IPv6 networks. The authorised ips, could be manually set IP by IP, or by subnet. E.g.:

IP: 192.168.1.123
Range: 192.168.1.1/24 

Configured IP adresses are automatically converted to subnets.

ip: 192.168.0.1 == range: 192.168.0.1/32

ip: 2001:db8:85a3::8a2e:370:7334 == range: 2001:0db8:85a3:0000:0000:8a2e:0370:7334/128

You can use subnet calculator to determinate the IPs, which will be whitelisted in the provided range. http://www.calculator.net/ip-subnet-calculator.html