Authentication¶
1 Principles¶
1.1 Account¶
In the platform a user having family data is called an account. An account may be authenticated on the platform and has:- One or several "account identifiers"
- A Password: Password of a user is stored in the databased with a BCrypt Hash
1.2 Account identifiers¶
Each user's account on the platform is identified by one or several identifiers. Identifier properties are:
- The 'type', which is an enum that may be:
- Email: an email
- Msisdn: a phone number
- ExternalId: the id of an external system (for SSO integration)
- Login: a login (free-form string)
- AccessToken: a random string being an identifier for a cryptographic authentication token
- SOMETHING_ELSE: reserved for extension mechanism.
- The 'value', which correspond to the type and must be totally unique across all users
1.3 Type of Authentication¶
The server APIs falls into two different categories:
- Account-based api :
API where the API call is relative to an account, such as wall/get (retrieve wall messages). Such APIs do always work on the user's account data or on the behalf of the Account, and the account in question is not passed as an explicit argument to the API. It is an implicit argument.
Such APIs mandate the caller to be authenticated and that the authentication corresponds to an account on the platform.
- Non-account-based api , such as createAccount:
API which does not consider the logged account as an implicit argument. Such APIs may mandate the client (or the calling application) to be authenticated, but does not mandate that the authentication correspond to an account on the platform. For instance, the client, or an administrator, shall be authenticated to perform such API calls, but they do not automatically correspond to an account.
As a result, an API call can be authenticated in two fashions:
- Client Authentication
Authentication recognizes the calling application and its associated rights to call this API.
- Account Authentication
Authentication recognizes the account and therefore enable calling account-based APIs.
Both authentication are enforced at the same time for each incoming request to the server.
1.4 Client authentication¶
1.4.1 API Access Right Ruleset¶
The Access Right ruleset is a set of rules indicating if each API is available or not depending on the client authentication.
For instance the ruleset "WEB" indicate that most of the APIs are accessible for clients authenticated as "WEB" but that some administration APIs are not.
Those rulesets are configured in the resource file accessrights.xml
1.4.2 Clients Id and Secret¶
Clients are authenticated by a clientId and a clientSecret, similarly as a login/password for a user.
Each clientId are allocated a given set of access rights that will correspond to:- Access Right RuleSet : a configured set of access right to indicate the authorized and forbidden APIs
- Client-type : Confidential or Public, indicating if the client is "internal" to FamilyWall or external.
- RedirectUrl : start of the authorized url redirection, needed for the web authentication.
- isOAuth2PasswordBasedAuthorized: indicate if the client is authorized to transport login/password information of the user, or required to go through the authorization server.
- name: the real name of the client
1.4.3 Client authorization errors¶
Whenever an API is called without client authentication and is not in the NOAUTHENT Access Right ruleset, the following error is returned to the caller:
501 : FizAccountNotFoundInSessionException (account-based authentication required)
509 : FizApiKeyInsufficientRightsException (client-based authentication required)
1.4.4 ClientId HTTP authentication¶
While performing an HTTP authentication, clientId and ClientSecret may be send in the HTTP request in several way
using HTTP parameters, either in post or in get, either in the URL or in an url-encoded part (single part or multipart). For instance:
GET /api?a01call=xxxxxx&client_id=1-2-3-3-2&client_secret=azerty HTTP/1.1
using HTTP Authenticate header, with a basic scheme. The value of the header shall be the concatenated string of clientId and clientSecret separated by a colon and base64-encoded. For instance:
POST /token HTTP/1.1 Authorization: Basic MS0yLTMtMy0yOmF6ZXJ0eQ==
And MS0yLTMtMy0yOmF6ZXJ0eQ== is the base64-encoding of 1-2-3-3-2:azerty , 1-2-3-3-2 being the clientId and azerty being the clientSecret.
1.5 HTTP Sessions¶
The API support (and even requires for performance reason) a session concept over HTTP.
At any time during an HTTP API call the server MAY respond with an additional Set-Cookie HTTP header, setting a JSESSIONID http cookies.
At any subsequent call the the server, the client MUST return the JSESSION id cookie, and ONLY this cookie. The cookie time-to-live on the client may be short and shall, if possible, correspond to a user session, if applicable.
At any time the server may invalidate an HTTP session and resend a JSESSIONID. However the server shall implement an HTTP session time-to-live based on a 30 minutes timeout after the latest access.
3 OAuth2 Authentication¶
3.1 OAuth2 Presentation¶
The system is able to use various OAuth2 authentication scenarios to provide access to account-based APIs.
Based on The OAuth 2.0 Authorization Protocol (draft-ietf-oauth-v2-31) (see http://datatracker.ietf.org/doc/draft-ietf-oauth-v2/ )
The principle is that the client must obtain an Access-Token and a Refresh-Token from the server, and then use the Access-Token to authenticate itself and use account-based APIs. In order to obtain the Access-Token and the Refresh-Token, the client must use HTTPS/TLS.
The type of access-token managed by the server is "MAC Access Authentication" or "BEARER Access Authentication".
Based on HTTP Authentication: MAC Access Authentication, draft-ietf-oauth-v2-http-mac-01 (see http://datatracker.ietf.org/doc/draft-ietf-oauth-v2-http-mac/ )
Based on HTTP Authentication: Bearer : draft-ietf-oauth-v2-bearer-22.pdf (see http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-23 )
The MAC Access Token is secure enough in order to be used on plain http connection instead of HTTPS/TLS. However his time-to-live is medium-lived (ie several days). When an Access Token is obsolete, the client must use the Refresh Token to obtain a new Access Token, using HTTPS/TLS. The Refresh Token is much more long lived (several years).
The Access-Token is used by signing an http request with the token secret with a hmac algorithm and put the signature in the Authorization Header of the http request.
The Bearer Access Token is not secure enough to be used over plain http connection, therefore when using a bearer token, using HTTPS/TLS is mandatory when performing API calls.
Note that this authentication mechanism does not alleviate the client from handling the HTTP Sessions cookies. However the HTTP sessions will be transparently recreated automatically if the session cookie is missing from the client.
In order to retrieve the Access-Token or the Refresh-Token, several scenario are possible, depending on the type of application, the type of client, etc...
The following scenario are implemented:
Exchange against login/password (for privileged clients)
The client must use the " log2generateaccesstokenbypassword " api to exchange the login/password of the user with an access token.
Exchange against a validation token (for privileged clients)
The client must use the " log2generateaccesstokenbyvalidationtoken " api to exchange a validation token with an access token, the validation tokens may come from privileged SSO integrations.
Exchange against an authorization code (for non-privileged clients)
The client must obtain an authorization code from the authorization server, enabling secure third-party authentication.
Privileged clients are recognized because their isOAuth2PasswordBasedAuthorized flag is set to true.
3.2 OAuth2 error codes¶
When an access token is required and missing the following error is returned to the client:
HTTP/1.1 401 Unauthorized WWW-Authenticate: MAC
or
HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer
When an access token is obsolete the following error is returned to the client:
HTTP/1.1 401 Unauthorized WWW-Authenticate: MAC Expired
3.4 Getting an Access Token for privileged application¶
log2generateaccesstokenbypassword¶
The client must:
Provide a client_id and client_secret to identify itself (using basic_auth or client_id and client_secret HTTP parameters)
Provide a deviceId (as in the devicesetconfig api) to identify the device.
The type of desired token (either Bearer or Mac)
Must perform his call using HTTPS
Example:
GET /api?a01call=log2generateaccesstokenbypassword&a01identifier=margesimpsontest&a01password=marge&a01tokentype=Bearer&a01deviceId=1-2-3-4-5&client_id=1-2-3-3-2&client_secret=azerty HTTP/1.1
In this example, the client gets his accessToken by using the user's credentials margesimpsontest/marge .
His device is identified by 1-2-3-4-5
The client key is 1-2-3-3-2 / azerty
The requested token type is "Bearer"
For the response, see 3.6
log2generateaccesstokenbyvalidationtoken¶
The client must:
Provide a client_id and client_secret to identify itself (using basic_auth or client_id and client_secret http parameters)
Provide a deviceId (as in the devicesetconfig api) to identify the device
The type of desired token (either Bearer or Mac)
Must perform his call using HTTPS
Example:
GET /api?a01call=log2generateaccesstokenbyvalidationtoken&a01validationtoken=123token123&a01tokentype=Bearer&a01deviceId=1-2-3-4-5&client_id=1-2-3-3-2&client_secret=azerty HTTP/1.1
In this example, the client gets his accessToken by using the validation token 123token123 .
His device is identified by 1-2-3-4-5
The client key is 1-2-3-3-2 / azerty
The requested token type is "Bearer"
For the response, see 3.6
3.5 Refresh Token usage¶
In order to use the refresh token, the client must present the refresh token to the /token endpoint in HTTPS/TLS.
See #6 of IETF OAuth specification.
Example:
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded;charset=UTF-8 grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
Note: Authorization headers shall contains the clientId/clientSecret for the client authorization. For there, all access performed with the Access-token will be considered as client-authenticated with those credentials. It is mandatory.
3.6 Access-Token response format¶
As defined in both ietf specification, the access token will be returned in JSON.
The only type of access-token managed is "mac".
The only type of max algorithm managed is "hmac-sha-1".
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"mac",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"mac_key":"AEZRDF41424aezraezr",
"mac_algorithm","hmac-sha-1"
}
3.7 Using the Bearer access-token to generate Authorization request.¶
It is fairly simple.
You just need to add an http basic-auth authorization header.
Example:
POST /API HTTP/1.1 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
3.8 Using the MAC SHA1 access-token to generate Authorization request.¶
It is actually all explained here : draft-ietf-oauth-v2-http-mac-01 , but I will summarize the procedure here:
- Generate the request Timetsamp in seconds
- Generate a random number to be used as a nonce
- From the request being done, extract the HOST, PORT, HTTP_METHOD, and FULL_PATH_OF_QUERY
- Concatenate all Timestamp, nonce, and information extracted from request into a string
- Compute the hmac of the concatenated string with the mac_key
- Generate and add an Authorization header in the http request
The format of the Authorization header is:
Authorization: MAC id="h480djs93hd8",
ts="1336363200",
nonce="dj83hs9s",
mac="bhCQXTVyfj5cmA9uKkPFx1zeOXM="
The id is the "access_token" value, the ts is the timestamp, the nonce is (well) the nonce, and the mac is the result of the hmac computation.
5 Third-party Oauth Authentication¶
This authentication method enables a third-party application to access a user's account on his behalf, after the user has specifically authorized the application to perform such access.The third-party authentication rely on a web-based technology for the authorization servers to authenticate the user and deliver the authorization. In this setup the involved entities are:
- User: the user of the third-party application and FamilyWall application
- User-Agent: the client application the user have to access both applications, capable or rendering web-pages (ie a browser or a native application rendering a web-view)
- TPY Server: the third-party server who wants to access the user's account on the FamilyWall server
- FamilyWall authorization server: the FamilyWall authorization server who will authenticate the user and ask for his permission before delivering the autorization.
+----------+
| User |
| |
+----------+
^
|
(C)
+----|-----+ Challenge authorize +---------------+
| +----(C)-- return login form ---->| FamilyWall |
| User- | | Authorization |
| Agent +<---(D)-- Challenge response ----| Server |
| | | |
| | | |
+-|----|---+ +---------------+
| | ^ v
(A) (D) | |
| | | |
^ v | |
+---------+ | |
| |>---(B)-- Request Authorize ----------' |
| TPY | Response Challenge authorize (redirect) |
| Server | |
| |>---(E)-- generate access token with code ---'
+---------+
The steps are:
A: Through the User-Agent, the user is authenticated to the TPY server and trigger an authorization request.¶
B: The TPY server is requesting an authorization procedure to the FamilyWall Authorization Server¶
In this authorization request, the TPY server sends:- his client_id
- the parameter response_type with value equals "code"
- a state parameter for his own usage
- the redirect_uri, that must match what is defined in his client authentication and his client_id in "RedirectUrl" (ie redirect_uri must starts with RedirectUrl)
Example:
GET /authorize?response_type=code&state=xyz&client_id=1-2-3-3-2&redirect_uri=https%3A%2F%2Fwww%2Etpyserver%2Ecom%2Freturn HTTP/1.1
The response consists in an HTTP redirect 302 to the FamilyWall authorization server. Example:
HTTP/1.1 302 Found Location: https://servername/challenge?jsessionid=D6C709DCDDAEC347A8C4E51620F4CD20.pre1
Note that the authorization server is using a session id parameter to set-up a server-side context of the authorization.
The TPY server shall send this redirect back to the user-agent, and the user-agent will follow the redirect.
C: The User-Agent will fetch the authorization challenge and return a login form¶
The Login form contains the name of the TPY server and is explicit about the requested authorization.
The user-agent will display the form to the user, and the user will authenticate to the FamilyWall server and authorize the TPY server to access his account.
D: The Familywall Authorization server return the authorization code¶
If the user successfully authenticate and authorize, The FamilyWall Server register this authorization and return an authorization code to the TPY server:
HTTP/1.1 302 Found Location: https://www.tpyserver.com/return?code=adienaEEFez1348233ZEFGH123AcTT&state=xyz
The TPY server can retrieve the authorization code and his private state.
E: The TPY server exchange the authorization code for an access token and a refresh token¶
The client must:
Provide a client_id and client_secret to identify itself, and it must match the one used on the authorization code
Provide the authorization code
The type of desired token (either Bearer or Mac)
Must perform his call using HTTPS
Example:
GET /api?a01call=log2generateaccesstokenbyauthorizationcode&a01code=adienaEEFez1348233ZEFGH123AcTT&a01tokentype=Bearer&client_id=1-2-3-3-2&client_secret=azerty HTTP/1.1
The response is the same as for the other apis, see "Access-Token response format".
Updated by Eric Vieillevigne over 10 years ago · 3 revisions