Device Token authn.
17.2.2.6.3.4. Device Token Authentication

The REST client has been authenticated in the above steps.

Authenticating using username + password + device token - as shown in the following steps - makes sense after logout (or on a different session).

To logout via the REST API call

DELETE /auth-login/rest/public/authentication

The start of the authentication process is the same as above: send username and password.

HTTP Request: Check Username and Password

copy
POST /auth-login/rest/public/authentication/password/check

{
    "password" : "1234",
    "username" : "jdoe"
}

HTTP Response: Check Username and Password

copy
HTTP/1.1 200 OK

{
    "meta": {
        "type": "jsonapi.metadata.document",
        "timestamp": "2018-02-13T09:49:17.994+01:00"
    },
    "data": {
        "type": "authentication.session",
        "id": "67449287",
        "attributes": {
            "nextAuthStep": "SELECTION_REQUIRED"
        }
    }
}

Since there is at least one valid device token for the user, the REST API server gives the client a choice of several second factors (in this example: MTAN or Device Token).

To get the list of options, the REST client can send the following request.

If the REST client already knows what to select, the next step can be omited (not recommended).

HTTP Request: Get Selection Options

copy
POST /auth-login/rest/public/authentication/selection/options

Http Response: 2nd-factor options that can be selected

copy
HTTP/1.1 200 OK

{
    "meta": {
        "type": "jsonapi.metadata.document",
        "timestamp": "2018-02-13T09:52:05.926+01:00"
    },
    "data": [
        {
            "type": "authentication.selection.option",
            "id": "DEVICE_TOKEN",
            "attributes": {}
        },
        {
            "type": "authentication.selection.option",
            "id": "MTAN",
            "attributes": {}
        }
    ]
}

If the option "MTAN" is selected, the authentication process continues as above using MTAN.

To continue with the device token, select "DEVICE_TOKEN".

HTTP Request: Select DEVICE_TOKEN as 2nd step

copy
POST /auth-login/rest/public/authentication/selection/options/DEVICE_TOKEN/select

Http Response from selecting DEVICE_TOKEN: a device token response is required

copy
HTTP/1.1 200 OK

{
    "meta": {
        "type": "jsonapi.metadata.document",
        "timestamp": "2018-02-13T09:55:27.497+01:00"
    },
    "data": {
        "type": "authentication.session",
        "id": "67449287",
        "attributes": {
            "nextAuthStep": "DEVICE_TOKEN_RESPONSE_REQUIRED"
        }
    }
}

The REST API asks for a "device token response", i.e. a signed challenge in the form of a JWT.

To do so, get a challenge first - using the device token ID that has been stored in the HTTP client when registering the public key.

HTTP Request: Get a device token challenge

copy
POST /auth-login/rest/public/authentication/device-token/110/challenge

Http Response: Device token challenge with expiration date

copy
HTTP/1.1 200 OK

{
    "meta": {
        "type": "jsonapi.metadata.document",
        "timestamp": "2018-02-13T09:58:53.578+01:00"
    },
    "data": {
        "type": "authentication.device-token.challenge",
        "id": "2503540437",
        "attributes": {
            "challenge": "fF46SgSBRyZM3P83ctRYIddpR29Ow26nK5thY7lq7y-KaTI0Pc5RD7ls8jAhx2Yx9qtYdX9iNQ0wWqgEHAK1Og",
            "validTo": "2018-02-13T10:08:53.519+01:00"
        }
    }
}

The challenge is only valid for a certain amount of time as reported by the validTo attribute (e.g. 10 minutes after getting the challenge) and can only be used once.

To respond to the challenge (see next call), create a JWT as follows:

  • Send back the challenge as "challenge" claim
  • Sign using the ES512 algorithm using the private key stored in the REST client

The "payload" of the JWT in this example would look like:

{
  "challenge": "fF46SgSBRyZM3P83ctRYIddpR29Ow26nK5thY7lq7y-KaTI0Pc5RD7ls8jAhx2Yx9qtYdX9iNQ0wWqgEHAK1Og"
}

The resulting JWT including the signature can be seen in the next example REST call.

HTTP Request: Send JWT for verification

copy
POST /auth-login/rest/public/authentication/device-token/check

{
  "jwt" : "eyJhbGciOiJFUzUxMiJ9.eyJjaGFsbGVuZ2UiOiJmRjQ2U2dTQlJ5Wk0zUDgzY3RSWUlkZHBSMjlPdzI2bks1dGhZN2xxN3ktS2FUSTBQYzVSRDdsczhqQWh4Mll4OXF0WWRYOWlOUTB3V3FnRUhBSzFPZyJ9.AYhSBk0odEpjV-73pDbsuBmdoFSJ4L_orHY8tTiN_-bqm1mYO82HaAeJqfDHlSTOladxXxCaCtvL2tTsKL5ri9jrAYX67zQ8dQYgl9fua4MNj3w8gAXm49faOgOVD86uCwrk3XvUQOJ8Teu9YyJkAMB-D_KL26wssa6PoAu2h3xCU9nX"
}

Http Response: Authentication succesful

copy
HTTP/1.1 200 OK

{
    "meta": {
        "type": "jsonapi.metadata.document",
        "timestamp": "2018-02-13T10:00:54.157+01:00"
    },
    "data": {
        "type": "authentication.session",
        "id": "67449287",
        "attributes": {}
    }
}