Project

General

Profile

Authentication Principle » History » Version 1

Eric Vieillevigne, 05/12/2015 01:50 PM

1 1 Eric Vieillevigne
h1. Authentication
2
3
h1. 1 Principles
4
5
h2. 1.1 Account
6
7
In the platform a user having family data is called an account. An account may be authenticated on the platform and has:
8
* One or several "account identifiers"
9
* A Password: Password of a user is stored in the databased with a BCrypt Hash
10
11
h2. 1.2 Account identifiers
12
13
Each user's account on the platform is identified by one or several identifiers. Identifier properties are:
14
15
* The 'type', which is an enum that may be: 
16
> * Email: an email
17
> * Msisdn: a phone number (not used at the moment)
18
> * ExternalId: the id of an external system (for SSO integration)
19
> * Login: a login (free-form string)
20
> * AccessToken: a random string being an identifier for a cryptographic authentication token
21
> * SOMETHING_ELSE: reserved for extension mechanism.
22
23
* The 'value', which correspond to the type and must be totally unique across all users
24
25
h2. 1.3 Type of Authentication 
26
27
The server APIs falls into two different categories: 
28
29
- _*Account-based api*_ :
30
> 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. 
31
> Such apis mandate the caller to be authenticated and that the authentication corresponds to an account on the platform.
32
33
- _*Non-account-based api*_ , such as createAccount:
34
> 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, may be authenticated to perform such api calls, but they do not automatically correspond to an account.
35
36
As a result, an api call can be authenticated in two fashions:
37
38
- _*Client Authentication*_
39
> Authentication recognize the calling application and associated right to call one or another api
40
41
- _*Account Authentication*_
42
> Authentication recognize the account and therefore enable calling account-based api.
43
44
> Both authentication can be available at the same time.
45
46
h2. 1.4 Client authentication
47
48
h2. 1.4.1 Api Access Right Ruleset
49
50
An Access Right ruleset is a set of rules indicating if each api is available or not.
51
For instance the ruleset "WEB" indicate that most of the API are accessible by this ruleset but that some administration api are not.
52
Those rulesets are configured in the resource file accessrights.xml
53
54
h2. 1.4.2 Clients Id and Secret
55
56
Clients are authenticated by a *clientId* and a *clientSecret*, similarly as a login/password for a user.
57
58
Each client are allocated a given set of access rights that will correspond to:
59
# Access Right RuleSet : a configured set of access right to indicate the authorized and forbidden apis
60
# Client-type : Confidential or Public, indicating if the 
61
# RedirectUrl : start of the authorized url redirection, needed for the web authentification
62
# isOAuth2PasswordBasedAuthorized: indicate if the client is authorized to transport login/password information of the user
63
# name: the real name of the client
64
65
Clients are authenticated with Oauth2 in a standard way and with WEB authentication. Legacy authentication does not support client authentication.
66
67
h3. 1.4.3 Client authorization errors
68
69
Whenever an API is called without client authentification and is not in the NOAUTHENT Access Right ruleset, the following error is returned to the caller:
70
501 : FizAccountNotFoundInSessionException
71
509 : FizApiKeyInsufficientRightsException
72
73
h2. 1.5 HTTP Sessions
74
75
The api support (and even requires for performance reason) a session concept over HTTP.
76
77
At any time during an HTTP api call the server _MAY_ respond with an additional Set-Cookie HTTP header, setting a JSESSIONID http cookies.
78
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.
79
80
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 lastest access.
81
82
h1. 2 LEGACY authentication based on the http session
83
84
> This Authentication scheme will be deprecated in the future, because it does not support Client Authentication, and is poorly secure.
85
 
86
This authentication scheme consist in calling the log2in api priori to any other account-based API. Non account-based apis are left unauthenticated.
87
By calling the log2in api, the identifier/password are passed to the system and verified. The identifier must correspond to an account's identifier and the password must pass the hash test of the corresponding account.
88
89
If the authentication is successful, the current HTTP session will become Account Authenticated up to the end of the HTTP Session. 
90
91
The api log2out may be called to remove the account authentication from the current HTTP Session. This will also invalidate the current HTTP session.
92
93
Because an http session can be invalidated by the server at any time (or almost at any time, the server _SHALL_ implement a 30 minutes timeouts after the last call on a session), the client _SHALL_ be ready to manage any 501:FizAccountNotFoundInSessionException errors and redo a log2in call.
94
95
When this authentication scheme is used, the Access Right Ruleset used (indicating which api can be called and which cannot) is LEGACY
96
97
h2. 2.1 Authorization errors:
98
99
Whenever an account-based api is called without an account authentication, the following error will be returned to the caller:
100
501 :  FizAccountNotFoundInSessionException
101
102
h2. 2.2 ISSUES WITH HTTP SESSION AUTHENTIFICATION
103
104
*MERGE METHOD* : merge method in account are not compatible with header auths
105
106
*RESET PASSWORD* : must be authenticated with a email token, which is one-time use token
107
108
*INVITATION* : must be authenticated with an email token, which may be used several time during a given period
109
110
*CREATEACCOUNT* : create account API shall return an AccessToken instead of letting the HTTP SESSION API Alive
111
112
*PREVIOUSLOGINDATE* : We store the PREVIOUS LOGIN DATE in the http session to perform some magic, this must be REMOVED
113
However this is used in the WEB for the numbers in the notification badge in the family menu, this MUST be redesigned anyway (or not ?) it can still be used if it is only on the WEB.
114
115
*LASTLOGINDATE* : we need to change to policy of this update
116
WE MUST MOVE THE CODE FROM AccountLoginApiImpl.loginAccountFromIdentifier to somewhere else...
117
118
h1. 3 OAuth2 Authentication
119
120
h2. 3.1 OAuth2 Presentation
121
122
The system is able to use various (but not all) OAuth2 authentication scenarios to provide access to account-based apis.
123
124
> Based on The OAuth 2.0 Authorization Protocol (draft-ietf-oauth-v2-31) (see http://datatracker.ietf.org/doc/draft-ietf-oauth-v2/ )
125
126
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.
127
128
The type of access-token managed by the server is "MAC Access Authentication" .
129
130
> 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/ )
131
132
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).
133
134
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.
135
136
> Based on HTPT Authentication: Bearer : draft-ietf-oauth-v2-bearer-22.pdf (see http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-23 )
137
138
> Note that this authentication mechanism does not aleviate the client from handling the HTTP Sessions cookies. However the HTTP sessions will be transparently recreated and re-authenticated and the usage of the log2in api is not necessary anymore.
139
140
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...
141
The following scenario are implemented:
142
143
> Exchange against login/password (for privilegied clients)
144
145
The client must use the " log2generateaccesstokenbypassword " api to exchange the login/password of the user with an access token.
146
147
> Exchange against a validation token (for privilegied clients)
148
149
The client must use the " log2generateaccesstokenbyvalidationtoken " api to exchange a validation token with an access token.
150
151
152
153
h2. 3.2 OAuth2 error codes
154
155
When an access token is required and missing the following error is returned to the client:
156
157
<pre>
158
HTTP/1.1 401 Unauthorized
159
  WWW-Authenticate: MAC
160
</pre>
161
162
or 
163
164
<pre>
165
HTTP/1.1 401 Unauthorized
166
  WWW-Authenticate: Bearer
167
</pre>
168
169
When an access token is obsolete the following error is returned to the client:
170
171
<pre>
172
HTTP/1.1 401 Unauthorized
173
  WWW-Authenticate: MAC Expired
174
</pre>
175
176
For other errors the WWW-Authenticate will provide various error messages.
177
178
h2. 3.3 Compatibility with authentication based on the http session
179
180
Normally, resource protected by OAuth will deny access of any request that do not have a valid Authorization Header.
181
However, when using the "Simple login/password authentication based on the http session" (see #2.0) concurrently, we have the following policy:
182
183
For accessing account-based apis:
184
# Any http request passed with an http session identified authentified with the "Simple login/password authentication based on the http session" will not require the OAuth 2.0 authentification
185
# Any other http request will requires the OAuth Authorization http header
186
187
For non-account-based apis, for the moment they are left unauthentified while we implement security on non-account based apis.
188
189
h2. 3.4 Getting an Access Token for privilegied application
190
191
h3. log2generateaccesstokenbypassword
192
193
The client must:
194
> > Provide a client_id and client_secret to identify itself (using basic_auth or client_id and client_secret http parameters)
195
> > Provide a deviceId (as in the devicesetconfig api) to identify the device
196
> > The type of desired token (either Bearer or Mac)
197
> > Must perform his call using HTTPS
198
199
Example:
200
<pre>
201
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
202
</pre>
203
204
In this example, the client gets his accessToken by using the user's credentials margesimpsontest/marge .
205
206
> His device is identified by 1-2-3-4-5
207
> The client key is 1-2-3-3-2 / azerty
208
> The requested token type is "Bearer"
209
210
For the response, see 3.6
211
212
h3. log2generateaccesstokenbyvalidationtoken
213
214
The client must:
215
> > Provide a client_id and client_secret to identify itself (using basic_auth or client_id and client_secret http parameters)
216
> > Provide a deviceId (as in the devicesetconfig api) to identify the device
217
> > The type of desired token (either Bearer or Mac)
218
> > Must perform his call using HTTPS
219
220
Example:
221
<pre>
222
GET /api?a01call=log2generateaccesstokenbyvalidationtoken&a01validationtoken=123token123&a01tokentype=Bearer&a01deviceId=1-2-3-4-5&client_id=1-2-3-3-2&client_password=azerty HTTP/1.1
223
</pre>
224
225
In this example, the client gets his accessToken by using the validation token 123token123 .
226
227
> His device is identified by 1-2-3-4-5
228
> The client key is 1-2-3-3-2 / azerty
229
> The requested token type is "Bearer"
230
231
For the response, see 3.6
232
233
h2. 3.5 Refresh Token usage
234
235
In order to use the refresh token, the client must present the refresh token to the /token endpoint in HTTPS/TLS.
236
See #6 of IETF OAuth specification.
237
238
Example:
239
<pre>
240
POST /token HTTP/1.1
241
  Host: server.example.com
242
  Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
243
  Content-Type: application/x-www-form-urlencoded;charset=UTF-8
244
  grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
245
</pre>
246
247
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.
248
249
h2. 3.6 Access-Token response format
250
251
As defined in both ietf specification, the access token will be returned in JSON.
252
The only type of access-token managed is "mac". 
253
The only type of max algorithm managed is "hmac-sha-1".
254
255
<pre>
256
HTTP/1.1 200 OK
257
  Content-Type: application/json;charset=UTF-8
258
  Cache-Control: no-store
259
  Pragma: no-cache
260
  {
261
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
262
    "token_type":"mac",
263
    "expires_in":3600,
264
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
265
	"mac_key":"AEZRDF41424aezraezr",
266
	"mac_algorithm","hmac-sha-1"
267
  }
268
</pre>
269
270
h2. 3.7 Using the Bearer access-token to generate Authorization request.
271
272
It is fairly simple.
273
You just need to add an http basic-auth authorization header.
274
Example:
275
276
<pre>
277
POST /API HTTP/1.1
278
  Authorization: Bearer aezraezrez:eazrraezraezraez
279
</pre>
280
281
282
h2. 3.8 Using the MAC SHA1 access-token to generate Authorization request.
283
284
It is actually all explained here : draft-ietf-oauth-v2-http-mac-01 , but I will summarize the procedure here:
285
286
# Generate the request Timetsamp in seconds
287
# Generate a random number to be used as a nonce
288
# From the request being done, extract the HOST, PORT, HTT_METHOD, and FULL_PATH_OF_QUERY
289
# Concatenate all Timestamp, nonce, and information extracted from request into a string
290
# Compute the hmac of the concatenated string with the mac_key
291
# Generate and add an Authorization header in the http request
292
293
The format of the Authorization header is:
294
<pre>
295
 Authorization: MAC id="h480djs93hd8",
296
                     ts="1336363200",
297
                     nonce="dj83hs9s",
298
                     mac="bhCQXTVyfj5cmA9uKkPFx1zeOXM="
299
</pre>
300
301
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.
302
303
h1. 5 WEB Oauth Authentification 
304
305
Web application authentication workflow is a derivated version of the oAuth2 protocol, but that does not requires the Authorization server to handle the display of the webpage himself.
306
307
The idea is to mandate that the client is authenticated (via his clientId/clientSecret) without exposing the clientSecret to the browser (note that in oAuth browser=user-agent).
308
309
In order to illustrate the process, we take the following hypothesis:
310
# User-Agent is a firefox browser, and it runs the main load of the application developped in Javascript.
311
# Webapp is build with PHP, and holds the secret. The secret is protected because it is sent to the User-Agent.
312
313
314
<pre>
315
316
  +----------+
317
  |   User   |
318
  |          |
319
  +----------+
320
       ^
321
       |
322
      (C)
323
  +----|-----+          User Login/Pwd         +---------------+
324
  |          +----(D)-- return JSESSIONID ---->|               |
325
  |  User-   |                                 |    FizApi     |
326
  |  Agent   +<---(E)-- JSESSIONID ------------|     Server    |
327
  |          |                                 |               |
328
  |          |                                 |               |
329
  +-|----|---+                                 +---------------+
330
    |    |                                         ^      v
331
   (A)  (F)                                        |      |
332
    |    |                                         |      |
333
    ^    v                                         |      |
334
  +---------+                                      |      |
335
  |         |>---(B)-- State Random Cypher---------'      |
336
  |  PHP    |      return StateSecret                     |
337
  |         |                                             |
338
  |         |>---(G)----- JSESSIONID   -------------------'
339
  +---------+       (client ID + Secret)
340
 
341
</pre>
342
343
A: User-Agent performs the first request to the PHP server to retrieve all the Javascript code of the webapp.
344
B: In order to initialize this Javascript, the PHP server is asking the FizApi server to generate a sessionSecret from a State Random Cypher (random generated by PHP)
345
A end: The PHP server is embedding the StateSecret in the Javascript code and returns the Javascript code to the user-agent
346
Because the sessionSecret is embedded in the Javascript, it will render screen-scraping more difficult, it shall be buried deep inside the Javascript, as obfuscated as possible.
347
348
C: The Javascript within the user-agent is presenting a "html form" to the user asking for his login/password and directed to the FizApi Server
349
   The form contains the State Random Cypher
350
   The user is submitting his login/password
351
352
D: The user-agent is submitting the form to the FizApi Server (directly without Javascript for Safari compatibility)
353
   Containing the login, password, and State Random Cypher.
354
355
E: The FizApi Server is validating the login/password, if it is valid, it opens a WEB api session and return the session identifier to the User-Agent.
356
   The session is still not client authenticated.
357
358
F: The Javascript in the user-agent is submitting to PHP the JSESSIONID and the StateSecret
359
360
G: The PHP is submitting the triplet (StateSecret,JSESSIONID,clientId+ClientSecret) in order to validate the JSESSIONID on the FizApi Server
361
The FizApi Server is validating that 
362
1) The StateSecret corresponds to the State Random Cypher for the same JSESSIONID, 
363
2) the clientId+ClientSecret are valid
364
The FizApi Server grants the session with the JSESSIONID with corresponding client Authorization. Any calls made by the user-agent to the FizApi server with this JESSIONID will be authorized.