Authentication Principle » History » Version 3
Eric Vieillevigne, 05/12/2015 06:13 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 | 2 | jerome bonnet | > * Msisdn: a phone number |
| 18 | 1 | Eric Vieillevigne | > * 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 | 2 | jerome bonnet | > 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 | 1 | Eric Vieillevigne | |
| 33 | - _*Non-account-based api*_ , such as createAccount: |
||
| 34 | 2 | jerome bonnet | > 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. |
| 35 | 1 | Eric Vieillevigne | |
| 36 | 2 | jerome bonnet | As a result, an API call can be authenticated in two fashions: |
| 37 | 1 | Eric Vieillevigne | |
| 38 | - _*Client Authentication*_ |
||
| 39 | 2 | jerome bonnet | > Authentication recognizes the calling application and its associated rights to call this API. |
| 40 | 1 | Eric Vieillevigne | |
| 41 | - _*Account Authentication*_ |
||
| 42 | 2 | jerome bonnet | > Authentication recognizes the account and therefore enable calling account-based APIs. |
| 43 | 1 | Eric Vieillevigne | |
| 44 | 2 | jerome bonnet | > Both authentication are enforced at the same time for each incoming request to the server. |
| 45 | 1 | Eric Vieillevigne | |
| 46 | h2. 1.4 Client authentication |
||
| 47 | |||
| 48 | 2 | jerome bonnet | h2. 1.4.1 API Access Right Ruleset |
| 49 | 1 | Eric Vieillevigne | |
| 50 | 2 | jerome bonnet | The Access Right ruleset is a set of rules indicating if each API is available or not depending on the client authentication. |
| 51 | 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. |
||
| 52 | 1 | Eric Vieillevigne | 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 | 2 | jerome bonnet | Each clientId 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 client is "internal" to FamilyWall or external. |
||
| 61 | # RedirectUrl : start of the authorized url redirection, needed for the web authentication. |
||
| 62 | # isOAuth2PasswordBasedAuthorized: indicate if the client is authorized to transport login/password information of the user, or required to go through the authorization server. |
||
| 63 | 1 | Eric Vieillevigne | # name: the real name of the client |
| 64 | |||
| 65 | h3. 1.4.3 Client authorization errors |
||
| 66 | |||
| 67 | 2 | jerome bonnet | 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: |
| 68 | 501 : FizAccountNotFoundInSessionException (account-based authentication required) |
||
| 69 | 509 : FizApiKeyInsufficientRightsException (client-based authentication required) |
||
| 70 | 1 | Eric Vieillevigne | |
| 71 | 2 | jerome bonnet | h3. 1.4.4 ClientId HTTP authentication |
| 72 | 1 | Eric Vieillevigne | |
| 73 | 2 | jerome bonnet | While performing an HTTP authentication, clientId and ClientSecret may be send in the HTTP request in several way |
| 74 | 1 | Eric Vieillevigne | |
| 75 | 2 | jerome bonnet | > 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: |
| 76 | 1 | Eric Vieillevigne | |
| 77 | 2 | jerome bonnet | <pre> |
| 78 | GET /api?a01call=xxxxxx&client_id=1-2-3-3-2&client_secret=azerty HTTP/1.1 |
||
| 79 | </pre> |
||
| 80 | 1 | Eric Vieillevigne | |
| 81 | 2 | jerome bonnet | > 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: |
| 82 | 1 | Eric Vieillevigne | |
| 83 | 2 | jerome bonnet | <pre> |
| 84 | POST /token HTTP/1.1 |
||
| 85 | Authorization: Basic MS0yLTMtMy0yOmF6ZXJ0eQ== |
||
| 86 | </pre> |
||
| 87 | 1 | Eric Vieillevigne | |
| 88 | 2 | jerome bonnet | 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. |
| 89 | 1 | Eric Vieillevigne | |
| 90 | 2 | jerome bonnet | h2. 1.5 HTTP Sessions |
| 91 | 1 | Eric Vieillevigne | |
| 92 | 2 | jerome bonnet | The API support (and even requires for performance reason) a session concept over HTTP. |
| 93 | 1 | Eric Vieillevigne | |
| 94 | 2 | jerome bonnet | At any time during an HTTP API call the server _MAY_ respond with an additional Set-Cookie HTTP header, setting a JSESSIONID http cookies. |
| 95 | 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. |
||
| 96 | 1 | Eric Vieillevigne | |
| 97 | 2 | jerome bonnet | 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. |
| 98 | 1 | Eric Vieillevigne | |
| 99 | |||
| 100 | h1. 3 OAuth2 Authentication |
||
| 101 | |||
| 102 | h2. 3.1 OAuth2 Presentation |
||
| 103 | |||
| 104 | 2 | jerome bonnet | The system is able to use various OAuth2 authentication scenarios to provide access to account-based APIs. |
| 105 | 1 | Eric Vieillevigne | |
| 106 | > Based on The OAuth 2.0 Authorization Protocol (draft-ietf-oauth-v2-31) (see http://datatracker.ietf.org/doc/draft-ietf-oauth-v2/ ) |
||
| 107 | |||
| 108 | 2 | jerome bonnet | 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. |
| 109 | 1 | Eric Vieillevigne | |
| 110 | 2 | jerome bonnet | The type of access-token managed by the server is "MAC Access Authentication" or "BEARER Access Authentication". |
| 111 | 1 | Eric Vieillevigne | |
| 112 | > 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/ ) |
||
| 113 | |||
| 114 | 2 | jerome bonnet | > Based on HTTP Authentication: Bearer : draft-ietf-oauth-v2-bearer-22.pdf (see http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-23 ) |
| 115 | |||
| 116 | 1 | Eric Vieillevigne | 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). |
| 117 | |||
| 118 | 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. |
||
| 119 | 2 | jerome bonnet | 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. |
| 120 | 1 | Eric Vieillevigne | |
| 121 | 2 | jerome bonnet | > 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. |
| 122 | 1 | Eric Vieillevigne | |
| 123 | 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... |
||
| 124 | The following scenario are implemented: |
||
| 125 | |||
| 126 | 2 | jerome bonnet | > Exchange against login/password (for privileged clients) |
| 127 | 1 | Eric Vieillevigne | |
| 128 | The client must use the " log2generateaccesstokenbypassword " api to exchange the login/password of the user with an access token. |
||
| 129 | |||
| 130 | 2 | jerome bonnet | > Exchange against a validation token (for privileged clients) |
| 131 | 1 | Eric Vieillevigne | |
| 132 | 2 | jerome bonnet | 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. |
| 133 | 1 | Eric Vieillevigne | |
| 134 | 2 | jerome bonnet | > Exchange against an authorization code (for non-privileged clients) |
| 135 | 1 | Eric Vieillevigne | |
| 136 | 2 | jerome bonnet | The client must obtain an authorization code from the authorization server, enabling secure third-party authentication. |
| 137 | 1 | Eric Vieillevigne | |
| 138 | 2 | jerome bonnet | > Privileged clients are recognized because their isOAuth2PasswordBasedAuthorized flag is set to true. |
| 139 | |||
| 140 | 1 | Eric Vieillevigne | h2. 3.2 OAuth2 error codes |
| 141 | |||
| 142 | When an access token is required and missing the following error is returned to the client: |
||
| 143 | |||
| 144 | <pre> |
||
| 145 | HTTP/1.1 401 Unauthorized |
||
| 146 | WWW-Authenticate: MAC |
||
| 147 | </pre> |
||
| 148 | |||
| 149 | or |
||
| 150 | |||
| 151 | <pre> |
||
| 152 | HTTP/1.1 401 Unauthorized |
||
| 153 | WWW-Authenticate: Bearer |
||
| 154 | </pre> |
||
| 155 | |||
| 156 | When an access token is obsolete the following error is returned to the client: |
||
| 157 | |||
| 158 | <pre> |
||
| 159 | HTTP/1.1 401 Unauthorized |
||
| 160 | WWW-Authenticate: MAC Expired |
||
| 161 | </pre> |
||
| 162 | |||
| 163 | 2 | jerome bonnet | h2. 3.4 Getting an Access Token for privileged application |
| 164 | 1 | Eric Vieillevigne | |
| 165 | h3. log2generateaccesstokenbypassword |
||
| 166 | |||
| 167 | The client must: |
||
| 168 | 2 | jerome bonnet | > > Provide a client_id and client_secret to identify itself (using basic_auth or client_id and client_secret HTTP parameters) |
| 169 | > > Provide a deviceId (as in the devicesetconfig api) to identify the device. |
||
| 170 | 1 | Eric Vieillevigne | > > The type of desired token (either Bearer or Mac) |
| 171 | > > Must perform his call using HTTPS |
||
| 172 | |||
| 173 | Example: |
||
| 174 | <pre> |
||
| 175 | 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 |
||
| 176 | </pre> |
||
| 177 | |||
| 178 | In this example, the client gets his accessToken by using the user's credentials margesimpsontest/marge . |
||
| 179 | |||
| 180 | > His device is identified by 1-2-3-4-5 |
||
| 181 | > The client key is 1-2-3-3-2 / azerty |
||
| 182 | > The requested token type is "Bearer" |
||
| 183 | |||
| 184 | For the response, see 3.6 |
||
| 185 | |||
| 186 | h3. log2generateaccesstokenbyvalidationtoken |
||
| 187 | |||
| 188 | The client must: |
||
| 189 | > > Provide a client_id and client_secret to identify itself (using basic_auth or client_id and client_secret http parameters) |
||
| 190 | > > Provide a deviceId (as in the devicesetconfig api) to identify the device |
||
| 191 | > > The type of desired token (either Bearer or Mac) |
||
| 192 | > > Must perform his call using HTTPS |
||
| 193 | |||
| 194 | Example: |
||
| 195 | <pre> |
||
| 196 | 2 | jerome bonnet | 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 |
| 197 | 1 | Eric Vieillevigne | </pre> |
| 198 | |||
| 199 | In this example, the client gets his accessToken by using the validation token 123token123 . |
||
| 200 | |||
| 201 | > His device is identified by 1-2-3-4-5 |
||
| 202 | > The client key is 1-2-3-3-2 / azerty |
||
| 203 | > The requested token type is "Bearer" |
||
| 204 | |||
| 205 | For the response, see 3.6 |
||
| 206 | |||
| 207 | h2. 3.5 Refresh Token usage |
||
| 208 | |||
| 209 | In order to use the refresh token, the client must present the refresh token to the /token endpoint in HTTPS/TLS. |
||
| 210 | See #6 of IETF OAuth specification. |
||
| 211 | |||
| 212 | Example: |
||
| 213 | <pre> |
||
| 214 | POST /token HTTP/1.1 |
||
| 215 | Host: server.example.com |
||
| 216 | Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW |
||
| 217 | Content-Type: application/x-www-form-urlencoded;charset=UTF-8 |
||
| 218 | grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA |
||
| 219 | </pre> |
||
| 220 | |||
| 221 | 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. |
||
| 222 | |||
| 223 | h2. 3.6 Access-Token response format |
||
| 224 | |||
| 225 | As defined in both ietf specification, the access token will be returned in JSON. |
||
| 226 | The only type of access-token managed is "mac". |
||
| 227 | The only type of max algorithm managed is "hmac-sha-1". |
||
| 228 | |||
| 229 | <pre> |
||
| 230 | HTTP/1.1 200 OK |
||
| 231 | Content-Type: application/json;charset=UTF-8 |
||
| 232 | Cache-Control: no-store |
||
| 233 | Pragma: no-cache |
||
| 234 | { |
||
| 235 | "access_token":"2YotnFZFEjr1zCsicMWpAA", |
||
| 236 | "token_type":"mac", |
||
| 237 | "expires_in":3600, |
||
| 238 | "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", |
||
| 239 | "mac_key":"AEZRDF41424aezraezr", |
||
| 240 | "mac_algorithm","hmac-sha-1" |
||
| 241 | } |
||
| 242 | </pre> |
||
| 243 | |||
| 244 | h2. 3.7 Using the Bearer access-token to generate Authorization request. |
||
| 245 | |||
| 246 | It is fairly simple. |
||
| 247 | You just need to add an http basic-auth authorization header. |
||
| 248 | Example: |
||
| 249 | |||
| 250 | <pre> |
||
| 251 | POST /API HTTP/1.1 |
||
| 252 | 2 | jerome bonnet | Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA |
| 253 | 1 | Eric Vieillevigne | </pre> |
| 254 | |||
| 255 | |||
| 256 | h2. 3.8 Using the MAC SHA1 access-token to generate Authorization request. |
||
| 257 | |||
| 258 | It is actually all explained here : draft-ietf-oauth-v2-http-mac-01 , but I will summarize the procedure here: |
||
| 259 | |||
| 260 | # Generate the request Timetsamp in seconds |
||
| 261 | # Generate a random number to be used as a nonce |
||
| 262 | 2 | jerome bonnet | # From the request being done, extract the HOST, PORT, HTTP_METHOD, and FULL_PATH_OF_QUERY |
| 263 | 1 | Eric Vieillevigne | # Concatenate all Timestamp, nonce, and information extracted from request into a string |
| 264 | # Compute the hmac of the concatenated string with the mac_key |
||
| 265 | # Generate and add an Authorization header in the http request |
||
| 266 | |||
| 267 | The format of the Authorization header is: |
||
| 268 | <pre> |
||
| 269 | Authorization: MAC id="h480djs93hd8", |
||
| 270 | ts="1336363200", |
||
| 271 | nonce="dj83hs9s", |
||
| 272 | mac="bhCQXTVyfj5cmA9uKkPFx1zeOXM=" |
||
| 273 | </pre> |
||
| 274 | |||
| 275 | 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. |
||
| 276 | |||
| 277 | 2 | jerome bonnet | h1. 5 Third-party Oauth Authentication |
| 278 | 1 | Eric Vieillevigne | |
| 279 | 2 | jerome bonnet | 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. |
| 280 | 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: |
||
| 281 | # User: the user of the third-party application and FamilyWall application |
||
| 282 | # 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) |
||
| 283 | # TPY Server: the third-party server who wants to access the user's account on the FamilyWall server |
||
| 284 | # FamilyWall authorization server: the FamilyWall authorization server who will authenticate the user and ask for his permission before delivering the autorization. |
||
| 285 | 1 | Eric Vieillevigne | |
| 286 | <pre> |
||
| 287 | |||
| 288 | +----------+ |
||
| 289 | | User | |
||
| 290 | | | |
||
| 291 | +----------+ |
||
| 292 | ^ |
||
| 293 | | |
||
| 294 | (C) |
||
| 295 | 2 | jerome bonnet | +----|-----+ Challenge authorize +---------------+ |
| 296 | | +----(C)-- return login form ---->| FamilyWall | |
||
| 297 | | User- | | Authorization | |
||
| 298 | | Agent +<---(D)-- Challenge response ----| Server | |
||
| 299 | 1 | Eric Vieillevigne | | | | | |
| 300 | | | | | |
||
| 301 | +-|----|---+ +---------------+ |
||
| 302 | | | ^ v |
||
| 303 | 2 | jerome bonnet | (A) (D) | | |
| 304 | 1 | Eric Vieillevigne | | | | | |
| 305 | ^ v | | |
||
| 306 | +---------+ | | |
||
| 307 | 2 | jerome bonnet | | |>---(B)-- Request Authorize ----------' | |
| 308 | | TPY | Response Challenge authorize (redirect) | |
||
| 309 | | Server | | |
||
| 310 | | |>---(E)-- generate access token with code ---' |
||
| 311 | +---------+ |
||
| 312 | 1 | Eric Vieillevigne | |
| 313 | </pre> |
||
| 314 | |||
| 315 | 2 | jerome bonnet | The steps are: |
| 316 | 1 | Eric Vieillevigne | |
| 317 | 2 | jerome bonnet | h2. A: Through the User-Agent, the user is authenticated to the TPY server and trigger an authorization request. |
| 318 | 1 | Eric Vieillevigne | |
| 319 | 2 | jerome bonnet | h2. B: The TPY server is requesting an authorization procedure to the FamilyWall Authorization Server |
| 320 | 1 | Eric Vieillevigne | |
| 321 | 2 | jerome bonnet | In this authorization request, the TPY server sends: |
| 322 | # his client_id |
||
| 323 | # the parameter response_type with value equals "code" |
||
| 324 | # a state parameter for his own usage |
||
| 325 | # 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) |
||
| 326 | Example: |
||
| 327 | 1 | Eric Vieillevigne | |
| 328 | 2 | jerome bonnet | <pre> |
| 329 | 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 |
||
| 330 | </pre> |
||
| 331 | 1 | Eric Vieillevigne | |
| 332 | 2 | jerome bonnet | The response consists in an HTTP redirect 302 to the FamilyWall authorization server. Example: |
| 333 | |||
| 334 | <pre> |
||
| 335 | HTTP/1.1 302 Found |
||
| 336 | 3 | Eric Vieillevigne | Location: https://servername/challenge?jsessionid=D6C709DCDDAEC347A8C4E51620F4CD20.pre1 |
| 337 | 2 | jerome bonnet | </pre> |
| 338 | |||
| 339 | Note that the authorization server is using a session id parameter to set-up a server-side context of the authorization. |
||
| 340 | |||
| 341 | The TPY server shall send this redirect back to the user-agent, and the user-agent will follow the redirect. |
||
| 342 | |||
| 343 | h2. C: The User-Agent will fetch the authorization challenge and return a login form |
||
| 344 | |||
| 345 | The Login form contains the name of the TPY server and is explicit about the requested authorization. |
||
| 346 | 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. |
||
| 347 | |||
| 348 | h2. D: The Familywall Authorization server return the authorization code |
||
| 349 | |||
| 350 | If the user successfully authenticate and authorize, The FamilyWall Server register this authorization and return an authorization code to the TPY server: |
||
| 351 | |||
| 352 | <pre> |
||
| 353 | HTTP/1.1 302 Found |
||
| 354 | Location: https://www.tpyserver.com/return?code=adienaEEFez1348233ZEFGH123AcTT&state=xyz |
||
| 355 | </pre> |
||
| 356 | |||
| 357 | The TPY server can retrieve the authorization code and his private state. |
||
| 358 | |||
| 359 | h2. E: The TPY server exchange the authorization code for an access token and a refresh token |
||
| 360 | |||
| 361 | The client must: |
||
| 362 | > > Provide a client_id and client_secret to identify itself, and it must match the one used on the authorization code |
||
| 363 | > > Provide the authorization code |
||
| 364 | > > The type of desired token (either Bearer or Mac) |
||
| 365 | > > Must perform his call using HTTPS |
||
| 366 | |||
| 367 | Example: |
||
| 368 | <pre> |
||
| 369 | GET /api?a01call=log2generateaccesstokenbyauthorizationcode&a01code=adienaEEFez1348233ZEFGH123AcTT&a01tokentype=Bearer&client_id=1-2-3-3-2&client_secret=azerty HTTP/1.1 |
||
| 370 | </pre> |
||
| 371 | |||
| 372 | The response is the same as for the other apis, see "Access-Token response format". |