yahoo-eng-team team mailing list archive
-
yahoo-eng-team team
-
Mailing list archive
-
Message #80393
[Bug 1848342] [NEW] Duplicated entries in users API
Public bug reported:
System version
==============
Keystone: 14.0.1 (Rocky)
The error happens when I try to show a federated user via the user name as the key instead of using the ID
Reproducing the error:
======================
First of all, I created a user in my Identity Provider (Idp) that is
configured my KeyStone instance.
We use OpenID Connect protocol to create the federated environment. In
this test, the user created is
named as 'use_case'. At this moment, the user is not in the OpenStack
database, just in the Idp
(ephemeral user type).
Authenticating with the ephemeral federated user:
Let's see the database tables before the login process.
Users already created in the Idp (before the login):
select * from user;
+----------------------------------+-------+---------+--------------------+---------------------+----------------+-----------+
| id | extra | enabled |
default_project_id | created_at | last_active_at | domain_id |
+----------------------------------+-------+---------+--------------------+---------------------+----------------+-----------+
| 1b0ed400ec974420a3574a8788acc795 | {} | 1 | NULL
| 2019-09-16 20:06:39 | NULL | default |
+----------------------------------+-------+---------+--------------------+---------------------+----------------+-----------+
select * from local_user;
+-----+----------------------------------+-----------+-------+-------------------+----------------+
| id | user_id | domain_id | name |
failed_auth_count | failed_auth_at |
+-----+----------------------------------+-----------+-------+-------------------+----------------+
| 1 | 1b0ed400ec974420a3574a8788acc795 | default | admin |
0 | NULL |
+-----+----------------------------------+-----------+-------+-------------------+----------------+
select * from federated_user;
Empty set (0.00 sec)
So far, we have only the local user admin
Then, we execute the login using the ephemeral user that we created in
the IdP.
Let's the database state after the first login:
select * from user;
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
| id | extra
| enabled | default_project_id | created_at | last_active_at |
domain_id |
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
| 1b0ed400ec974420a3574a8788acc795 | {}
| 1 | NULL | 2019-09-16 20:06:39 | NULL |
default |
| f0327d98278f4b1881aec9c051b027d3 | {"email":
"use_case@xxxxxxxxx"} | 1 | NULL | 2019-10-15
18:08:17 | NULL | d28c2423e9b546deb37a034bb2134f4d |
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
select * from local_user;
+----+----------------------------------+-----------+-------+-------------------+----------------+
| id | user_id | domain_id | name |
failed_auth_count | failed_auth_at |
+----+----------------------------------+-----------+-------+-------------------+----------------+
| 1 | 1b0ed400ec974420a3574a8788acc795 | default | admin |
0 | NULL |
+----+----------------------------------+-----------+-------+-------------------+----------------+
select * from federated_user;
+----+----------------------------------+--------+-------------+-----------+--------------+
| id | user_id | idp_id | protocol_id |
unique_id | display_name |
+----+----------------------------------+--------+-------------+-----------+--------------+
| 1 | f0327d98278f4b1881aec9c051b027d3 | my_idp | openid |
use_case | use_case |
+----+----------------------------------+--------+-------------+-----------+--------------+
Here we can see that the user did not exist in OpenStack
database before the first login; then, KeyStone receives the user
attributes (during the authentication process) from the Idp and register
the user in the OpenStack database as a federated user.
(user and federated_user tables).
Here is the OpenStack client output (when executing the show
command after the first login):
openstack user show use_case
+---------------------+----------------------------------+
| Field | Value |
+---------------------+----------------------------------+
| domain_id | d28c2423e9b546deb37a034bb2134f4d |
| email | use_case@xxxxxxxxx |
| enabled | True |
| id | f0327d98278f4b1881aec9c051b027d3 |
| name | use_case |
| options | {} |
| password_expires_at | None |
+---------------------+----------------------------------+
Afterwards, we logout and then we login again in Horizon via the
IdP. Please invalidate your session, OpenStack has a bug, and it is not
invalidating IdP sessions when the logout is called in Horizon):
select * from user;
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
| id | extra
| enabled | default_project_id | created_at | last_active_at |
domain_id |
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
| 1b0ed400ec974420a3574a8788acc795 | {}
| 1 | NULL | 2019-09-16 20:06:39 | NULL |
default |
| f0327d98278f4b1881aec9c051b027d3 | {"email":
"use_case@xxxxxxxxx"} | 1 | NULL | 2019-10-15
18:08:17 | NULL | d28c2423e9b546deb37a034bb2134f4d |
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
select * from local_user;
+----+----------------------------------+----------------------------------+----------+-------------------+----------------+
| id | user_id | domain_id
| name | failed_auth_count | failed_auth_at |
+----+----------------------------------+----------------------------------+----------+-------------------+----------------+
| 1 | 1b0ed400ec974420a3574a8788acc795 | default
| admin | 0 | NULL |
| 4 | f0327d98278f4b1881aec9c051b027d3 |
d28c2423e9b546deb37a034bb2134f4d | use_case | 0 | NULL
|
+----+----------------------------------+----------------------------------+----------+-------------------+----------------+
select * from federated_user;
+----+----------------------------------+--------+-------------+-----------+--------------+
| id | user_id | idp_id | protocol_id |
unique_id | display_name |
+----+----------------------------------+--------+-------------+-----------+--------------+
| 1 | f0327d98278f4b1881aec9c051b027d3 | my_idp | openid |
use_case | use_case |
+----+----------------------------------+--------+-------------+-----------+--------------+
Here is the bug, the user already existed in the OpenStack
database, and during the second login, Keystone tried to update data
with the attributes that come from the IdP. During the update process,
Keystone will create an entry in the local_user table.
The code that is generating this behavior can be found in
https://github.com/openstack/keystone/blob/master/keystone/identity/core.py#L1421
After that, if I try to show the user via OpenStack client, I
receive the following error
openstack user show use_case
More than one user exists with the name 'use_case'.
Here is an excerpt of our Attribute Mapping JSON:
[
{
"local": [
{
"user": {
"name": "{0}",
"email": "{1}",
"domain": {
"name": "{2}"
}
},
"domain": {
"name": "{2}"
},
"projects": [
{
"name": "{3}",
"roles": [
{
"name": "member"
},
{
"name": "domadmin"
},
{
"name": "heat_stack_owner"
},
{
"name": "load-balancer_member"
}
]
}
]
}
],
"remote": [
{
"type": "OIDC-preferred_username"
},
{
"type": "OIDC-email"
},
{
"type": "OIDC-openstack-user-domain"
},
{
"type": "OIDC-openstack-default-project"
},
{
"type": "OIDC-openstack-user-role",
"any_one_of": [
"domain-admin"
]
}
]
},
{
"local": [
{
"user": {
"name": "{0}",
"email": "{1}",
"type": "local",
"domain": {
"name": "{2}"
}
},
"domain": {
"name": "{2}"
},
"projects": [
{
"name": "{3}",
"roles": [
{
"name": "member"
},
{
"name": "heat_stack_owner"
},
{
"name": "load-balancer_member"
}
]
}
]
}
],
"remote": [
{
"type": "OIDC-preferred_username"
},
{
"type": "OIDC-email"
},
{
"type": "OIDC-openstack-user-domain"
},
{
"type": "OIDC-openstack-default-project"
},
{
"type": "OIDC-openstack-user-status",
"any_one_of": [
"local"
]
},
{
"type": "OIDC-openstack-user-role",
"any_one_of": [
"member"
]
}
]
}
]
Here is a link to the PR that propose to fix that issue:
https://review.opendev.org/#/c/687990
** Affects: keystone
Importance: Undecided
Status: New
--
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to OpenStack Identity (keystone).
https://bugs.launchpad.net/bugs/1848342
Title:
Duplicated entries in users API
Status in OpenStack Identity (keystone):
New
Bug description:
System version
==============
Keystone: 14.0.1 (Rocky)
The error happens when I try to show a federated user via the user name as the key instead of using the ID
Reproducing the error:
======================
First of all, I created a user in my Identity Provider (Idp) that is
configured my KeyStone instance.
We use OpenID Connect protocol to create the federated environment. In
this test, the user created is
named as 'use_case'. At this moment, the user is not in the OpenStack
database, just in the Idp
(ephemeral user type).
Authenticating with the ephemeral federated user:
Let's see the database tables before the login process.
Users already created in the Idp (before the login):
select * from user;
+----------------------------------+-------+---------+--------------------+---------------------+----------------+-----------+
| id | extra | enabled |
default_project_id | created_at | last_active_at | domain_id
|
+----------------------------------+-------+---------+--------------------+---------------------+----------------+-----------+
| 1b0ed400ec974420a3574a8788acc795 | {} | 1 | NULL
| 2019-09-16 20:06:39 | NULL | default |
+----------------------------------+-------+---------+--------------------+---------------------+----------------+-----------+
select * from local_user;
+-----+----------------------------------+-----------+-------+-------------------+----------------+
| id | user_id | domain_id | name |
failed_auth_count | failed_auth_at |
+-----+----------------------------------+-----------+-------+-------------------+----------------+
| 1 | 1b0ed400ec974420a3574a8788acc795 | default | admin |
0 | NULL |
+-----+----------------------------------+-----------+-------+-------------------+----------------+
select * from federated_user;
Empty set (0.00 sec)
So far, we have only the local user admin
Then, we execute the login using the ephemeral user that we created in
the IdP.
Let's the database state after the first login:
select * from user;
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
| id | extra
| enabled | default_project_id | created_at | last_active_at
| domain_id |
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
| 1b0ed400ec974420a3574a8788acc795 | {}
| 1 | NULL | 2019-09-16 20:06:39 | NULL
| default |
| f0327d98278f4b1881aec9c051b027d3 | {"email":
"use_case@xxxxxxxxx"} | 1 | NULL | 2019-10-15
18:08:17 | NULL | d28c2423e9b546deb37a034bb2134f4d |
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
select * from local_user;
+----+----------------------------------+-----------+-------+-------------------+----------------+
| id | user_id | domain_id | name |
failed_auth_count | failed_auth_at |
+----+----------------------------------+-----------+-------+-------------------+----------------+
| 1 | 1b0ed400ec974420a3574a8788acc795 | default | admin |
0 | NULL |
+----+----------------------------------+-----------+-------+-------------------+----------------+
select * from federated_user;
+----+----------------------------------+--------+-------------+-----------+--------------+
| id | user_id | idp_id | protocol_id
| unique_id | display_name |
+----+----------------------------------+--------+-------------+-----------+--------------+
| 1 | f0327d98278f4b1881aec9c051b027d3 | my_idp | openid
| use_case | use_case |
+----+----------------------------------+--------+-------------+-----------+--------------+
Here we can see that the user did not exist in OpenStack
database before the first login; then, KeyStone receives the user
attributes (during the authentication process) from the Idp and
register the user in the OpenStack database as a federated user.
(user and federated_user tables).
Here is the OpenStack client output (when executing the show
command after the first login):
openstack user show use_case
+---------------------+----------------------------------+
| Field | Value |
+---------------------+----------------------------------+
| domain_id | d28c2423e9b546deb37a034bb2134f4d |
| email | use_case@xxxxxxxxx |
| enabled | True |
| id | f0327d98278f4b1881aec9c051b027d3 |
| name | use_case |
| options | {} |
| password_expires_at | None |
+---------------------+----------------------------------+
Afterwards, we logout and then we login again in Horizon via the
IdP. Please invalidate your session, OpenStack has a bug, and it is
not invalidating IdP sessions when the logout is called in Horizon):
select * from user;
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
| id | extra
| enabled | default_project_id | created_at | last_active_at
| domain_id |
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
| 1b0ed400ec974420a3574a8788acc795 | {}
| 1 | NULL | 2019-09-16 20:06:39 | NULL
| default |
| f0327d98278f4b1881aec9c051b027d3 | {"email":
"use_case@xxxxxxxxx"} | 1 | NULL | 2019-10-15
18:08:17 | NULL | d28c2423e9b546deb37a034bb2134f4d |
+----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+
select * from local_user;
+----+----------------------------------+----------------------------------+----------+-------------------+----------------+
| id | user_id | domain_id
| name | failed_auth_count | failed_auth_at |
+----+----------------------------------+----------------------------------+----------+-------------------+----------------+
| 1 | 1b0ed400ec974420a3574a8788acc795 | default
| admin | 0 | NULL |
| 4 | f0327d98278f4b1881aec9c051b027d3 |
d28c2423e9b546deb37a034bb2134f4d | use_case | 0 | NULL
|
+----+----------------------------------+----------------------------------+----------+-------------------+----------------+
select * from federated_user;
+----+----------------------------------+--------+-------------+-----------+--------------+
| id | user_id | idp_id | protocol_id
| unique_id | display_name |
+----+----------------------------------+--------+-------------+-----------+--------------+
| 1 | f0327d98278f4b1881aec9c051b027d3 | my_idp | openid
| use_case | use_case |
+----+----------------------------------+--------+-------------+-----------+--------------+
Here is the bug, the user already existed in the OpenStack
database, and during the second login, Keystone tried to update data
with the attributes that come from the IdP. During the update process,
Keystone will create an entry in the local_user table.
The code that is generating this behavior can be found in
https://github.com/openstack/keystone/blob/master/keystone/identity/core.py#L1421
After that, if I try to show the user via OpenStack client, I
receive the following error
openstack user show use_case
More than one user exists with the name 'use_case'.
Here is an excerpt of our Attribute Mapping JSON:
[
{
"local": [
{
"user": {
"name": "{0}",
"email": "{1}",
"domain": {
"name": "{2}"
}
},
"domain": {
"name": "{2}"
},
"projects": [
{
"name": "{3}",
"roles": [
{
"name": "member"
},
{
"name": "domadmin"
},
{
"name": "heat_stack_owner"
},
{
"name": "load-balancer_member"
}
]
}
]
}
],
"remote": [
{
"type": "OIDC-preferred_username"
},
{
"type": "OIDC-email"
},
{
"type": "OIDC-openstack-user-domain"
},
{
"type": "OIDC-openstack-default-project"
},
{
"type": "OIDC-openstack-user-role",
"any_one_of": [
"domain-admin"
]
}
]
},
{
"local": [
{
"user": {
"name": "{0}",
"email": "{1}",
"type": "local",
"domain": {
"name": "{2}"
}
},
"domain": {
"name": "{2}"
},
"projects": [
{
"name": "{3}",
"roles": [
{
"name": "member"
},
{
"name": "heat_stack_owner"
},
{
"name": "load-balancer_member"
}
]
}
]
}
],
"remote": [
{
"type": "OIDC-preferred_username"
},
{
"type": "OIDC-email"
},
{
"type": "OIDC-openstack-user-domain"
},
{
"type": "OIDC-openstack-default-project"
},
{
"type": "OIDC-openstack-user-status",
"any_one_of": [
"local"
]
},
{
"type": "OIDC-openstack-user-role",
"any_one_of": [
"member"
]
}
]
}
]
Here is a link to the PR that propose to fix that issue:
https://review.opendev.org/#/c/687990
To manage notifications about this bug go to:
https://bugs.launchpad.net/keystone/+bug/1848342/+subscriptions
Follow ups