Add documentation for Auth Receipts and MFA

Adds API ref examples for TOTP and Auth receipts.

Adds docs for MFA and changes some of the user options
docs.

Change-Id: Id5497064e580093e4a2c7d904670a58095833b3b
This commit is contained in:
Adrian Turjak 2019-01-09 17:53:35 +13:00
parent a011fb6789
commit 6564b40641
13 changed files with 697 additions and 56 deletions

View File

@ -10,7 +10,7 @@ optionally, grants authorization on a specific project, domain, or the
deployment system. deployment system.
The body of an authentication request must include a payload that The body of an authentication request must include a payload that
specifies the authentication method, which is ``password`` or specifies the authentication methods, which are normally just ``password`` or
``token``, the credentials, and, optionally, the authorization ``token``, the credentials, and, optionally, the authorization
scope. You can scope a token to a project, domain, the deployment system, or scope. You can scope a token to a project, domain, the deployment system, or
the token can be unscoped. You cannot scope a token to multiple scope targets. the token can be unscoped. You cannot scope a token to multiple scope targets.
@ -18,6 +18,16 @@ the token can be unscoped. You cannot scope a token to multiple scope targets.
Tokens have IDs, which the Identity API returns in the Tokens have IDs, which the Identity API returns in the
``X-Subject-Token`` response header. ``X-Subject-Token`` response header.
In the case of multi-factor authentication (MFA) more than one authentication
method needs to be supplied to authenticate. As of v3.12 a failure due to MFA
rules only partially being met will result in an auth receipt ID being returned
in the response header ``Openstack-Auth-Receipt``, and a response body that
details the receipt itself and the missing authentication methods. Supplying
the auth receipt ID in the ``Openstack-Auth-Receipt`` header in a follow-up
authentication request, with the missing authentication methods, will result in
a valid token by reusing the successful methods from the first request. This
allows MFA authentication to be a multi-step process.
After you obtain an authentication token, you can: After you obtain an authentication token, you can:
- Make REST API requests to other OpenStack services. You supply the - Make REST API requests to other OpenStack services. You supply the
@ -74,6 +84,10 @@ These authentication errors can occur:
| | - The specified ``X-Auth-Token`` header is not valid. | | | - The specified ``X-Auth-Token`` header is not valid. |
| | | | | |
| | - The authentication credentials are not valid. | | | - The authentication credentials are not valid. |
| | |
| | - Not all MFA rules were satisfied. |
| | |
| | - The specified ``Openstack-Auth-Receipt`` header is not valid. |
+------------------------+----------------------------------------------------------------------+ +------------------------+----------------------------------------------------------------------+
| ``Forbidden (403)`` | The identity was successfully authenticated but it is not | | ``Forbidden (403)`` | The identity was successfully authenticated but it is not |
| | authorized to perform the requested action. | | | authorized to perform the requested action. |
@ -621,6 +635,168 @@ Example
:language: javascript :language: javascript
Multi-Step authentication (2-Factor Password and TOTP example)
==============================================================
.. rest_method:: POST /v3/auth/tokens
Authenticates an identity and generates a token. Uses the password
authentication method, then the totp method, with an auth receipt in between.
This assumes that MFA has been enabled for the user, and a rule has been
defined requiring authentication with both password and totp.
The first request body must at least include a payload that specifies one of
``password`` or ``totp`` authentication methods which includes the credentials
in addition to an optional scope. If only one method is supplied then an auth
receipt will be returned. Scope is not retained in the receipt and must be
resupplied in subsequent requests.
While it is very possible to supply all the required auth methods at once, this
example shows the multi-step process which is likely to be more common.
More than 2 factors can be used but the same process applies to those as well;
either all auth methods are supplied at once, or in steps with one or more auth
receipts in between.
Relationship: ``https://docs.openstack.org/api/openstack-identity/3/rel/auth_tokens``
First Request
-------------
Parameters
~~~~~~~~~~
.. rest_parameters:: parameters.yaml
- nocatalog: nocatalog
- name: user_name
- auth: auth
- user: user
- scope: scope_string
- password: password
- id: user_id
- identity: identity
- methods: auth_methods_passwd
Example
~~~~~~~
.. literalinclude:: ./samples/auth/requests/project-id-password.json
:language: javascript
Response
--------
Here we are expecting a 401 status, and a returned auth receipt.
Parameters
~~~~~~~~~~
.. rest_parameters:: parameters.yaml
- Openstack-Auth-Receipt: Openstack-Auth-Receipt
- methods: auth_methods_receipt
- expires_at: receipt_expires_at
- issued_at: receipt_issued_at
- user: user
- required_auth_methods: required_auth_methods
Status Code
~~~~~~~~~~~
.. rest_status_code:: success status.yaml
- 401: auth_receipt
.. rest_status_code:: error status.yaml
- 400
- 401: auth_failed
- 403
- 404
Auth Receipt Example
~~~~~~~~~~~~~~~~~~~~
.. literalinclude:: ./samples/auth/responses/auth-receipt-password.json
:language: javascript
Second Request
--------------
Parameters
~~~~~~~~~~
.. rest_parameters:: parameters.yaml
- Openstack-Auth-Receipt: Openstack-Auth-Receipt
- nocatalog: nocatalog
- name: user_name
- auth: auth
- user: user
- scope: scope_string
- totp: totp
- id: user_id
- identity: identity
- methods: auth_methods_totp
Example
~~~~~~~
.. literalinclude:: ./samples/auth/requests/project-id-totp.json
:language: javascript
Response
--------
Parameters
~~~~~~~~~~
.. rest_parameters:: parameters.yaml
- X-Subject-Token: X-Subject-Token
- region_id: region_id_required
- methods: auth_methods_passwd
- roles: roles
- url: endpoint_url
- region: endpoint_region
- token: token
- expires_at: expires_at
- system: system_scope_response_body_optional
- domain: domain_scope_response_body_optional
- project: project_scope_response_body_optional
- issued_at: issued_at
- catalog: catalog
- user: user
- audit_ids: audit_ids
- interface: endpoint_interface
- endpoints: endpoints
- type: endpoint_type
- id: user_id
- name: user_name
Status Codes
~~~~~~~~~~~~
.. rest_status_code:: success status.yaml
- 201
.. rest_status_code:: error status.yaml
- 400
- 401: auth_receipt_failure
- 403
- 404
Project-Scoped Password and TOTP Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. literalinclude:: ./samples/auth/responses/project-scoped-password-totp.json
:language: javascript
Validate and show information for token Validate and show information for token
======================================= =======================================

View File

@ -1,4 +1,12 @@
# variables in header # variables in header
Openstack-Auth-Receipt:
description: |
The auth receipt. A partially successful authentication
response returns the auth receipt ID in this header rather than in the
response body.
in: header
required: true
type: string
X-Auth-Token: X-Auth-Token:
description: | description: |
A valid authentication token for an A valid authentication token for an
@ -477,8 +485,8 @@ auth_domain:
type: object type: object
auth_methods: auth_methods:
description: | description: |
The authentication method, which is ``password``, The authentication methods, which are commonly ``password``,
``token``, or both methods. Indicates the accumulated set of ``token``, or other methods. Indicates the accumulated set of
authentication methods that were used to obtain the token. For authentication methods that were used to obtain the token. For
example, if the token was obtained by password authentication, it example, if the token was obtained by password authentication, it
contains ``password``. Later, if the token is exchanged by using contains ``password``. Later, if the token is exchanged by using
@ -506,6 +514,19 @@ auth_methods_passwd:
in: body in: body
required: true required: true
type: array type: array
auth_methods_receipt:
description: |
The authentication methods, which are commonly ``password``,
``totp``, or other methods. Indicates the accumulated set of
authentication methods that were used to obtain the receipt. For
example, if the receipt was obtained by password authentication, it
contains ``password``. Later, if the receipt is exchanged by using
another authentication method one or more times, the
subsequently created receipts could contain both ``password`` and
``totp`` in their ``methods`` attribute.
in: body
required: true
type: array
auth_methods_token: auth_methods_token:
description: | description: |
The authentication method. For token The authentication method. For token
@ -513,6 +534,13 @@ auth_methods_token:
in: body in: body
required: true required: true
type: array type: array
auth_methods_totp:
description: |
The authentication method. For totp
authentication, specify ``totp``.
in: body
required: true
type: array
auth_token: auth_token:
description: | description: |
A ``token`` object. The token authentication A ``token`` object. The token authentication
@ -1433,6 +1461,38 @@ projects:
in: body in: body
required: true required: true
type: array type: array
receipt_expires_at:
description: |
The date and time when the receipt expires.
The date and time stamp format is `ISO 8601
<https://en.wikipedia.org/wiki/ISO_8601>`_:
::
CCYY-MM-DDThh:mm:ss.sssZ
For example, ``2015-08-27T09:49:58.000000Z``.
A ``null`` value indicates that the receipt never expires.
in: body
required: true
type: string
receipt_issued_at:
description: |
The date and time when the receipt was issued.
The date and time stamp format is `ISO 8601
<https://en.wikipedia.org/wiki/ISO_8601>`_:
::
CCYY-MM-DDThh:mm:ss.sssZ
For example, ``2015-08-27T09:49:58.000000Z``.
in: body
required: true
type: string
region_id_not_required: region_id_not_required:
description: | description: |
(Since v3.2) The ID of the region that contains (Since v3.2) The ID of the region that contains
@ -1604,6 +1664,13 @@ request_service_id_registered_limit_body_not_required:
in: body in: body
required: false required: false
type: string type: string
required_auth_methods:
description: |
A list of authentication rules that may be used with the auth receipt
to complete the authentication process.
in: body
required: true
type: list of lists
resource_limit: resource_limit:
description: | description: |
The override limit. The override limit.
@ -1909,6 +1976,12 @@ token:
in: body in: body
required: true required: true
type: object type: object
totp:
description: |
The ``totp`` object, contains the authentication information.
in: body
required: true
type: object
user: user:
description: | description: |
A ``user`` object. A ``user`` object.

View File

@ -0,0 +1,20 @@
{
"auth": {
"identity": {
"methods": [
"totp"
],
"totp": {
"user": {
"id": "ee4dfb6e5540447cb3741905149d9b6e",
"passcode": "123456"
}
}
},
"scope": {
"project": {
"id": "a6944d763bf64ee6a275f1263fae0352"
}
}
}
}

View File

@ -0,0 +1,20 @@
{
"receipt":{
"expires_at":"2018-07-05T08:39:23.000000Z",
"issued_at":"2018-07-05T08:34:23.000000Z",
"methods": [
"password"
],
"user": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "ee4dfb6e5540447cb3741905149d9b6e",
"name": "admin"
}
},
"required_auth_methods": [
["totp", "password"]
]
}

View File

@ -0,0 +1,67 @@
{
"token": {
"audit_ids": [
"3T2dc1CGQxyJsHdDu1xkcw"
],
"catalog": [
{
"endpoints": [
{
"id": "068d1b359ee84b438266cb736d81de97",
"interface": "public",
"region": "RegionOne",
"region_id": "RegionOne",
"url": "http://example.com/identity"
},
{
"id": "8bfc846841ab441ca38471be6d164ced",
"interface": "admin",
"region": "RegionOne",
"region_id": "RegionOne",
"url": "http://example.com/identity"
},
{
"id": "beb6d358c3654b4bada04d4663b640b9",
"interface": "internal",
"region": "RegionOne",
"region_id": "RegionOne",
"url": "http://example.com/identity"
}
],
"type": "identity",
"id": "050726f278654128aba89757ae25950c",
"name": "keystone"
}
],
"expires_at": "2015-11-07T02:58:43.578887Z",
"is_domain": false,
"issued_at": "2015-11-07T01:58:43.578929Z",
"methods": [
"password",
"totp"
],
"project": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "a6944d763bf64ee6a275f1263fae0352",
"name": "admin"
},
"roles": [
{
"id": "51cc68287d524c759f47c811e6463340",
"name": "admin"
}
],
"user": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "ee4dfb6e5540447cb3741905149d9b6e",
"name": "admin",
"password_expires_at": "2016-11-06T15:32:17.000000"
}
}
}

View File

@ -27,6 +27,14 @@
401: 401:
default: | default: |
User must authenticate before making a request. User must authenticate before making a request.
auth_failed: |
Authentication attempt has failed.
auth_receipt: |
User has successfully supplied some auth methods, but not enough for full
authentication.
auth_receipt_failure: |
Authentication attempt has failed. Either the auth receipt has expired, or
the additional auth methods supplied were invalid.
403: 403:
default: | default: |
Policy does not allow current user to do this operation. Policy does not allow current user to do this operation.

View File

@ -11,6 +11,8 @@
License for the specific language governing permissions and limitations License for the specific language governing permissions and limitations
under the License. under the License.
.. _auth_totp:
=================================== ===================================
Time-based One-time Password (TOTP) Time-based One-time Password (TOTP)
=================================== ===================================

View File

@ -8,6 +8,7 @@ user and password method.
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
multi-factor-authentication
auth-totp auth-totp
federation/federated_identity federation/federated_identity
external-authentication external-authentication

View File

@ -0,0 +1,88 @@
.. _multi_factor_authentication:
===========================
Multi-Factor Authentication
===========================
Configuring MFA
===============
MFA is configured on a per user basis via the user options
:ref:`multi_factor_auth_rules` and :ref:`multi_factor_auth_enabled`. Until
these are set the user can authenticate with any one of the enabled auth
methods.
MFA rules
---------
The MFA rules allow an admin to force a user to use specific forms of
authentication or combinations of forms of authentication to get a token.
The rules are specified as follows via the user option
:ref:`multi_factor_auth_rules`::
[["password", "totp"], ["password", "custom-auth-method"]]
They are a list of lists. The elements of the sub-lists must be strings and are
intended to mirror the required authentication method names (e.g. ``password``,
``totp``, etc) as defined in the ``keystone.conf`` file in the
``[auth] methods`` option. Each list of methods specifies a rule.
If the auth methods provided by a user match (or exceed) the auth methods in
the list, that rule is used. The first rule found (rules will not be processed
in a specific order) that matches will be used. If a user has the ruleset
defined as ``[["password", "totp"]]`` the user must provide both password and
totp auth methods (and both methods must succeed) to receive a token. However,
if a user has a ruleset defined as ``[["password"], ["password", "totp"]]``
the user may use the ``password`` method on it's own but would be required
to use both ``password`` and ``totp`` if ``totp`` is specified at all.
Any auth methods that are not defined in ``keystone.conf`` in the
``[auth] methods`` option are ignored when the rules are processed. Empty
rules are not allowed. If a rule is empty due to no-valid auth methods
existing within it, the rule is discarded at authentication time. If there
are no rules or no valid rules for the user, authentication occurs in the
default manner: any single configured auth method is sufficient to receive
a token.
.. note::
The ``token`` auth method typically should not be specified in any MFA
Rules. The ``token`` auth method will include all previous auth methods
for the original auth request and will match the appropriate ruleset. This
is intentional, as the ``token`` method is used for rescoping/changing
active projects.
Enabling MFA
------------
Before the MFA rules take effect on a user, MFA has to be enabled for that user
via the user option :ref:`multi_factor_auth_enabled`. By default this is unset,
and the rules will not take effect until configured.
In the case a user should be exempt from MFA Rules, regardless if they are
set, the User-Option may be set to ``False``.
Using MFA
=========
See :ref:`multi_factor_authentication_user_guide` in the user guide for some
examples.
Supported multi-factor authentication methods
=============================================
TOTP is the only suggested second factor along with password for now, but there
are plans to include more in future.
TOTP
----
This is a simple 6 digit passcode generated by both the server and client from
a known shared secret.
This used in a multi-step fashion is the most common 2-factor method used these
days.
See: :ref:`auth_totp`

View File

@ -22,6 +22,28 @@ User Options
The following options are available on user resources. If left undefined, they The following options are available on user resources. If left undefined, they
are assumed to be false or disabled. are assumed to be false or disabled.
These can be set either in the initial user creation (``POST /v3/users``)
or by updating an existing user to include new options
(``PATCH /v3/users/{user_id}``):
.. code-block:: json
{
"user": {
"options": {
"ignore_lockout_failure_attempts": true
}
}
}
.. note::
User options of the ``Boolean`` type can be set to ``True``, ``False``, or
``None``; if the option is set to ``None``, it is removed from the user's
data structure.
.. _ignore_change_password_upon_first_use:
ignore_change_password_upon_first_use ignore_change_password_upon_first_use
------------------------------------- -------------------------------------
@ -32,9 +54,21 @@ they log into keystone for the first time. This can be useful for deployments
that auto-generate passwords but want to ensure a user picks a new password that auto-generate passwords but want to ensure a user picks a new password
when they start using the deployment. when they start using the deployment.
.. code-block:: json
{
"user": {
"options": {
"ignore_change_password_upon_first_use": true
}
}
}
See the `security compliance documentation See the `security compliance documentation
<security-compliance.html>`_ for more details. <security-compliance.html>`_ for more details.
.. _ignore_password_expiry:
ignore_password_expiry ignore_password_expiry
---------------------- ----------------------
@ -45,9 +79,21 @@ Opt into ignoring global password expiration settings defined in
option to ``True`` will allow users to continue using passwords that may be option to ``True`` will allow users to continue using passwords that may be
expired according to global configuration values. expired according to global configuration values.
.. code-block:: json
{
"user": {
"options": {
"ignore_password_expiry": true
}
}
}
See the `security compliance documentation See the `security compliance documentation
<security-compliance.html>`_ for more details. <security-compliance.html>`_ for more details.
.. _ignore_lockout_failure_attempts:
ignore_lockout_failure_attempts ignore_lockout_failure_attempts
------------------------------- -------------------------------
@ -56,9 +102,21 @@ Type: ``Boolean``
If ``True``, opt into ignoring the number of times a user has authenticated and If ``True``, opt into ignoring the number of times a user has authenticated and
locking out the user as a result. locking out the user as a result.
.. code-block:: json
{
"user": {
"options": {
"ignore_lockout_failure_attempts": true
}
}
}
See the `security compliance documentation See the `security compliance documentation
<security-compliance.html>`_ for more details. <security-compliance.html>`_ for more details.
.. _lock_password:
lock_password lock_password
------------- -------------
@ -67,9 +125,22 @@ Type: ``Boolean``
If set to ``True``, this option disables the ability for users to change their If set to ``True``, this option disables the ability for users to change their
password through self-service APIs. password through self-service APIs.
.. code-block:: json
{
"user": {
"options": {
"lock_password": true
}
}
}
See the `security compliance documentation See the `security compliance documentation
<security-compliance.html>`_ for more details. <security-compliance.html>`_ for more details.
.. _multi_factor_auth_enabled:
multi_factor_auth_enabled multi_factor_auth_enabled
------------------------- -------------------------
@ -80,6 +151,20 @@ This will result in different behavior at authentication time and the user may
be presented with different authentication requirements based on multi-factor be presented with different authentication requirements based on multi-factor
configuration. configuration.
.. code-block:: json
{
"user": {
"options": {
"multi_factor_auth_enabled": true
}
}
}
See :ref:`multi_factor_authentication` for further details.
.. _multi_factor_auth_rules:
multi_factor_auth_rules multi_factor_auth_rules
----------------------- -----------------------
@ -87,3 +172,19 @@ Type: ``List of Lists of Strings``
Define a list of strings that represent the methods required for a user to Define a list of strings that represent the methods required for a user to
authenticate. authenticate.
.. code-block:: json
{
"user": {
"options": {
"multi_factor_auth_rules": [
["password", "totp"],
["password", "u2f"]
]
}
}
}
See :ref:`multi_factor_authentication` for further details.

View File

@ -42,18 +42,7 @@ indefinitely until the user is explicitly enabled via the API.
You can ensure specific users are never locked out. This can be useful for You can ensure specific users are never locked out. This can be useful for
service accounts or administrative users. You can do this by setting service accounts or administrative users. You can do this by setting
``ignore_lockout_failure_attempts`` to ``true`` via a user update API the user option for :ref:`ignore_lockout_failure_attempts`.
(``PATCH /v3/users/{user_id}``):
.. code-block:: json
{
"user": {
"options": {
"ignore_lockout_failure_attempts": true
}
}
}
Disabling inactive users Disabling inactive users
------------------------ ------------------------
@ -85,18 +74,7 @@ authentication (first use), before being able to access any services.
Prior to enabling this feature, you may want to exempt some users that you do Prior to enabling this feature, you may want to exempt some users that you do
not wish to be required to change their password. You can mark a user as not wish to be required to change their password. You can mark a user as
exempt by setting the user options attribute exempt by setting the user options attribute
``ignore_change_password_upon_first_use`` to ``true`` via a user update API :ref:`ignore_change_password_upon_first_use`.
(``PATCH /v3/users/{user_id}``):
.. code-block:: json
{
"user": {
"options": {
"ignore_change_password_upon_first_use": true
}
}
}
.. WARNING:: .. WARNING::
@ -131,18 +109,7 @@ expiration date, you would need to run a SQL script against the password table
in the database to update the expires_at column. in the database to update the expires_at column.
If there exists a user whose password you do not want to expire, keystone If there exists a user whose password you do not want to expire, keystone
supports setting that user's option ``ignore_password_expiry`` to ``true`` supports setting that via the user option :ref:`ignore_password_expiry`.
via user update API (``PATCH /v3/users/{user_id}``):
.. code-block:: json
{
"user": {
"options": {
"ignore_password_expiry": true
}
}
}
Configuring password strength requirements Configuring password strength requirements
------------------------------------------ ------------------------------------------
@ -225,24 +192,11 @@ Prevent Self-Service Password Changes
------------------------------------- -------------------------------------
If there exists a user who should not be able to change her own password via If there exists a user who should not be able to change her own password via
the keystone password change API, keystone supports setting that user's option the keystone password change API, keystone supports setting that via the user
``lock_password`` to ``True`` via the user update API option :ref:`lock_password`.
(``PATCH /v3/users/{user_id}``):
.. code-block:: json This is typically used in the case where passwords are managed externally to
keystone.
{
"user": {
"options": {
"lock_password": true
}
}
}
The ``lock_password`` user-option is typically used in the case where passwords
are managed externally to keystone. The ``lock_password`` option can be set to
``True``, ``False``, or ``None``; if the option is set to ``None``, it is
removed from the user's data structure.
.. _Security Hardening PCI-DSS: https://specs.openstack.org/openstack/keystone-specs/specs/keystone/newton/pci-dss.html .. _Security Hardening PCI-DSS: https://specs.openstack.org/openstack/keystone-specs/specs/keystone/newton/pci-dss.html

View File

@ -30,3 +30,4 @@ An end user can find the specific API documentation here, `OpenStack's Identity
trusts.rst trusts.rst
json_home.rst json_home.rst
../api_curl_examples.rst ../api_curl_examples.rst
multi-factor-authentication.rst

View File

@ -0,0 +1,130 @@
.. _multi_factor_authentication_user_guide:
===========================
Multi-Factor Authentication
===========================
Configuring MFA
===============
Configuring MFA right now has to be done entirely by an admin, for how to do
that, see :ref:`multi_factor_authentication`.
Using MFA
=========
Multi-Factor Authentication with Keystone can be used in two ways, either you
treat it like current single method authentication and provide all the details
upfront, or you doing it as a multi-step process with auth receipts.
Single step
-----------
In the single step approach you would supply all the required authentication
methods in your request for a token.
Here is an example using 2 factors (``password`` and ``totp``):
.. code-block:: json
{ "auth": {
"identity": {
"methods": [
"password",
"totp"
],
"totp": {
"user": {
"id": "2ed179c6af12496cafa1d279cb51a78f",
"passcode": "012345"
}
},
"password": {
"user": {
"id": "2ed179c6af12496cafa1d279cb51a78f",
"password": "super sekret pa55word"
}
}
}
}
}
If all the supplied auth methods are valid, Keystone will return a token.
Multi-Step
----------
In the multi-step approach you can supply any one method from the auth rules:
Again we do a 2 factor example, starting with ``password``:
.. code-block:: json
{ "auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"id": "2ed179c6af12496cafa1d279cb51a78f",
"password": "super sekret pa55word"
}
}
}
}
}
Provided the method is valid, Keystone will still return a ``401``, but will in
the response header ``Openstack-Auth-Receipt`` return a receipt of valid auth
method for reuse later.
The response body will also contain information about the auth receipt, and
what auth methods may be missing:
.. code-block:: json
{
"receipt":{
"expires_at":"2018-07-05T08:39:23.000000Z",
"issued_at":"2018-07-05T08:34:23.000000Z",
"methods": [
"password"
],
"user": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "ee4dfb6e5540447cb3741905149d9b6e",
"name": "admin"
}
},
"required_auth_methods": [
["totp", "password"]
]
}
Now you can continue authenticating by supplying the missing auth methods, and
supplying the header ``Openstack-Auth-Receipt`` as gotten from the previous
response:
.. code-block:: json
{ "auth": {
"identity": {
"methods": [
"totp"
],
"totp": {
"user": {
"id": "2ed179c6af12496cafa1d279cb51a78f",
"passcode": "012345"
}
}
}
}
}
Provided the auth methods are valid, Keystone will now supply a token. If not
you can try again until the auth receipt expires (e.g in case of TOTP timeout).