Hi, I would like to configure the authentication of my Openstack instance with an external IDP ( Keycloak ) using the subordinate charm “keystone-saml-mellon”.
1 - Issue :
I can log in to Horizon with the admin
user on the admin_domain
, but I can’t log in to the Horizon dashboard with my external IDP ( Keycloak ), authentication seems to work but Keystone returns a 403 error :
"You are not authorized to perform the requested action."
2 - setup :
- opentsack is deployed with Juju and Maas.
- keycloak instance is working.
- keystone-saml-mellon instance is deployed via the bundle.
3 - My Bundle :
series: focal
applications:
keystone:
charm: cs:keystone-323
channel: stable
num_units: 1
to:
- lxd:6
options:
admin-password: password
debug: true
openstack-origin: distro
preferred-api-version: 3
region: RMV
token-expiration: 86400
token-provider: fernet
worker-multiplier: 0.25
bindings:
"": maas-infralab
admin: maas-infralab
certificates: maas-infralab
cluster: maas-infralab
domain-backend: maas-infralab
ha: maas-infralab
identity-admin: maas-infralab
identity-credentials: maas-infralab
identity-notifications: maas-infralab
identity-service: maas-infralab
internal: maas-infralab
keystone-fid-service-provider: maas-infralab
keystone-middleware: maas-infralab
nrpe-external-master: maas-infralab
public: maas-infralab
shared-db: maas-infralab
websso-trusted-dashboard: maas-infralab
keystone-mysql-router:
charm: cs:mysql-router-4
channel: stable
bindings:
"": maas-infralab
certificates: maas-infralab
db-router: maas-infralab
juju-info: maas-infralab
shared-db: maas-infralab
mysql-innodb-cluster:
charm: cs:mysql-innodb-cluster-7
channel: stable
num_units: 3
to:
- lxd:6
- lxd:6
- lxd:6
options:
enable-binlogs: true
innodb-buffer-pool-size: 8G
max-connections: 4000
tuning-level: safest
wait-timeout: 3600
bindings:
"": maas-infralab
certificates: maas-infralab
cluster: maas-infralab
coordinator: maas-infralab
db-router: maas-infralab
shared-db: maas-infralab
openstack-dashboard:
charm: cs:openstack-dashboard-313
channel: stable
num_units: 1
to:
- lxd:6
options:
cinder-backup: false
endpoint-type: publicURL
enforce-ssl: false
neutron-network-l3ha: true
neutron-network-lb: true
openstack-origin: distro
password-retrieve: true
webroot: /
constraints: spaces=maas-infralab
bindings:
"": maas-infralab
certificates: maas-infralab
cluster: maas-infralab
dashboard-plugin: maas-infralab
ha: maas-infralab
identity-service: maas-infralab
nrpe-external-master: maas-infralab
public: maas-infralab
shared-db: maas-infralab
website: maas-infralab
websso-fid-service-provider: maas-infralab
websso-trusted-dashboard: maas-infralab
openstack-dashboard-mysql-router:
charm: cs:mysql-router-4
channel: stable
bindings:
"": maas-infralab
certificates: maas-infralab
db-router: maas-infralab
juju-info: maas-infralab
shared-db: maas-infralab
public-policy-routing:
charm: cs:advanced-routing-4
channel: stable
options:
action-managed-update: false
advanced-routing-config: |-
[{
"type": "table",
"table": "public"
},{
"type": "route",
"default_route": true,
"gateway": "10.140.8.1",
"table": "public",
"metric": "101"
},{
"type": "rule",
"from-net": "10.140.8.0/22",
"table": "public",
"priority": "101"
},{
"type": "rule",
"from-net": "10.140.8.0/22",
"to-net": "10.140.8.0/22"
}]
enable-advanced-routing: true
bindings:
"": alpha
juju-info: alpha
rabbitmq-server:
charm: cs:rabbitmq-server-110
channel: stable
num_units: 1
to:
- lxd:6
options:
min-cluster-size: 1
source: distro
bindings:
"": maas-infralab
amqp: maas-infralab
certificates: maas-infralab
cluster: maas-infralab
ha: maas-infralab
nrpe-external-master: maas-infralab
keystone-saml-mellon1:
charm: cs:~openstack-charmers-next/keystone-saml-mellon
num_units: 0
options:
idp-name: 'test-saml-idp1'
protocol-name: 'mapped'
user-facing-name: "Keycloak"
subject-confirmation-data-address-check: False
nameid-formats: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
bindings:
"": maas-infralab
certificates: maas-infralab
container: maas-infralab
keystone-fid-service-provider: maas-infralab
websso-fid-service-provider: maas-infralab
keycloak1:
charm: cs:ubuntu
bindings:
"": maas-infralab
num_units: 1
to:
- lxd:6
machines:
"6":
constraints: tags=mellon zones=default
relations:
- - openstack-dashboard:identity-service
- keystone:identity-service
- - public-policy-routing:juju-info
- keystone:juju-info
- - public-policy-routing:juju-info
- openstack-dashboard:juju-info
- - keystone:shared-db
- keystone-mysql-router:shared-db
- - openstack-dashboard:shared-db
- openstack-dashboard-mysql-router:shared-db
- - mysql-innodb-cluster:db-router
- keystone-mysql-router:db-router
- - mysql-innodb-cluster:db-router
- openstack-dashboard-mysql-router:db-router
- - 'keystone'
- 'keystone-saml-mellon1'
- - 'openstack-dashboard'
- 'keystone-saml-mellon1'
- - 'keystone:websso-trusted-dashboard'
- 'openstack-dashboard:websso-trusted-dashboard'
4 - Keystone :
I have created the following items in Keystone:
- domain
- group
- projects
- identity provider
- mapping
- federation protocol
openstack domain show 61470a6fc93f42a39c35c1c271295329
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | |
| enabled | True |
| id | 61470a6fc93f42a39c35c1c271295329 |
| name | federated_domain |
| options | {} |
| tags | [] |
+-------------+----------------------------------+
openstack group show d3cb5d52bced4a85992469f48a5e292d --domain federated_domain
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | |
| domain_id | 61470a6fc93f42a39c35c1c271295329 |
| id | d3cb5d52bced4a85992469f48a5e292d |
| name | federated_users |
+-------------+----------------------------------+
openstack project show a0aaabaec75f4e76b65b681486be5410
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | |
| domain_id | 61470a6fc93f42a39c35c1c271295329 |
| enabled | True |
| id | a0aaabaec75f4e76b65b681486be5410 |
| is_domain | False |
| name | federated_project |
| options | {} |
| parent_id | 61470a6fc93f42a39c35c1c271295329 |
| tags | [] |
+-------------+----------------------------------+
openstack identity provider show test-saml-idp1
+-------------------+----------------------------------+
| Field | Value |
+-------------------+----------------------------------+
| authorization_ttl | None |
| description | None |
| domain_id | 61470a6fc93f42a39c35c1c271295329 |
| enabled | True |
| id | test-saml-idp1 |
| remote_ids | test-saml-idp1 |
+-------------------+----------------------------------+
openstack mapping show samltest_mapping
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | samltest_mapping |
| rules | [{'local': [{'user': {'name': '{0}', 'domain': {'name': 'federated_domain'}}, 'group': {'domain': {'name': 'federated_domain'}, 'name': 'federated_users'}}], 'remote': [{'type': 'MELLON_NAME_ID'}]}] |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
openstack federation protocol show mapped --identity-provider test-saml-idp1
+---------+------------------+
| Field | Value |
+---------+------------------+
| id | mapped |
| mapping | samltest_mapping |
+---------+------------------+
My full log output of keystone after a login attempt :
(keystone.server.flask.request_processing.req_logging): 2022-03-01 13:05:11,600 DEBUG REQUEST_METHOD: `GET`
(keystone.server.flask.request_processing.req_logging): 2022-03-01 13:05:11,600 DEBUG SCRIPT_NAME: ``
(keystone.server.flask.request_processing.req_logging): 2022-03-01 13:05:11,600 DEBUG PATH_INFO: `/v3/auth/OS-FEDERATION/identity_providers/test-saml-idp1/protocols/mapped/websso`
(keystone.api._shared.authentication): 2022-03-01 13:05:11,602 DEBUG No 'external' plugin is registered.
(keystone.federation.utils): 2022-03-01 13:05:11,603 DEBUG Environment variables: {'MELLON_NAME_ID': 'karim@cloud.local', 'MELLON_Role': 'default-roles-master;view-profile;uma_authorization;offline_access;manage-account;manage-account-links', 'MELLON_IDP': 'http://10.140.8.45:8080/auth/realms/master', 'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PROTOCOL': 'HTTP/1.1', 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'origin=http://10.140.8.39/auth/websso/', 'REQUEST_URI': '/v3/auth/OS-FEDERATION/identity_providers/test-saml-idp1/protocols/mapped/websso?origin=http://10.140.8.39/auth/websso/', 'SCRIPT_NAME': '', 'PATH_INFO': '/v3/auth/OS-FEDERATION/identity_providers/test-saml-idp1/protocols/mapped/websso', 'PATH_TRANSLATED': '/usr/bin/keystone-wsgi-public/v3/auth/OS-FEDERATION/identity_providers/test-saml-idp1/protocols/mapped/websso', 'HTTP_HOST': '10.140.8.44:5000', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_CACHE_CONTROL': 'max-age=0', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7', 'HTTP_COOKIE': 'mellon-cookie=c5ac749baa950cd91e0023d02e358222', 'SERVER_SIGNATURE': '<address>Apache/2.4.41 (Ubuntu) Server at 10.140.8.44 Port 5000</address>\n', 'SERVER_SOFTWARE': 'Apache/2.4.41 (Ubuntu)', 'SERVER_NAME': '10.140.8.44', 'SERVER_ADDR': '10.140.8.44', 'SERVER_PORT': '5000', 'REMOTE_ADDR': '10.140.8.44', 'DOCUMENT_ROOT': '/var/www/html', 'REQUEST_SCHEME': 'http', 'CONTEXT_PREFIX': '', 'CONTEXT_DOCUMENT_ROOT': '/var/www/html', 'SERVER_ADMIN': '[no address given]', 'SCRIPT_FILENAME': '/usr/bin/keystone-wsgi-public', 'REMOTE_PORT': '34316', 'REMOTE_USER': 'karim@cloud.local', 'AUTH_TYPE': 'Mellon', 'mod_wsgi.script_name': '', 'mod_wsgi.path_info': '/v3/auth/OS-FEDERATION/identity_providers/test-saml-idp1/protocols/mapped/websso', 'mod_wsgi.process_group': 'keystone-public', 'mod_wsgi.application_group': '', 'mod_wsgi.callable_object': 'application', 'mod_wsgi.request_handler': 'wsgi-script', 'mod_wsgi.handler_script': '', 'mod_wsgi.script_reloading': '1', 'mod_wsgi.listener_host': '', 'mod_wsgi.listener_port': '4990', 'mod_wsgi.enable_sendfile': '0', 'mod_wsgi.ignore_activity': '0', 'mod_wsgi.request_start': '1646139911593747', 'mod_wsgi.request_id': 'E1+u0Ee3gqs', 'mod_wsgi.queue_start': '1646139911594016', 'mod_wsgi.daemon_connects': '1', 'mod_wsgi.daemon_restarts': '0', 'mod_wsgi.daemon_start': '1646139911594458', 'mod_wsgi.script_start': '1646139911595436', 'wsgi.version': (1, 0), 'wsgi.multithread': False, 'wsgi.multiprocess': True, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.errors': <_io.TextIOWrapper name='<wsgi.errors>' encoding='utf-8'>, 'wsgi.input': <oslo_middleware.sizelimit.LimitingReader object at 0x7f20b83c2550>, 'wsgi.input_terminated': True, 'wsgi.file_wrapper': <class 'mod_wsgi.FileWrapper'>, 'apache.version': (2, 4, 41), 'mod_wsgi.version': (4, 6, 8), 'mod_wsgi.total_requests': 2, 'mod_wsgi.thread_id': 1, 'mod_wsgi.thread_requests': 2, 'werkzeug.proxy_fix.orig': {'REMOTE_ADDR': '10.140.8.44', 'wsgi.url_scheme': 'http', 'HTTP_HOST': '10.140.8.44:5000', 'SERVER_NAME': '10.140.8.44', 'SERVER_PORT': '5000', 'SCRIPT_NAME': ''}, 'werkzeug.proxy_fix.orig_remote_addr': '10.140.8.44', 'werkzeug.proxy_fix.orig_wsgi_url_scheme': 'http', 'werkzeug.proxy_fix.orig_http_host': '10.140.8.44:5000', 'webob.adhoc_attrs': {'response': <_AuthTokenResponse at 0x7f20b83c2e50 200 OK>}, 'webob.is_body_seekable': False, 'openstack.request_id': 'req-a71cce8e-9aae-4cc3-9d90-8bc6e590b141', 'keystone.token_auth': <keystonemiddleware.auth_token._user_plugin.UserAuthPlugin object at 0x7f20b83c28b0>, 'keystone.oslo_request_context': <keystone.common.context.RequestContext object at 0x7f20b83c24f0>, 'werkzeug.request': <Request 'http://10.140.8.44:5000/v3/auth/OS-FEDERATION/identity_providers/test-saml-idp1/protocols/mapped/websso?origin=http:%2F%2F10.140.8.39%2Fauth%2Fwebsso%2F' [GET]>}
(sqlalchemy.orm.path_registry): 2022-03-01 13:05:11,606 DEBUG set 'memoized_setups' on path 'EntityRegistry((<Mapper at 0x7f20b8a90af0; IdentityProviderModel>,))' to '{}'
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,607 INFO Connection <pymysql.connections.Connection object at 0x7f20b8715310> exceeded timeout; recycling
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,607 DEBUG Closing connection <pymysql.connections.Connection object at 0x7f20b8715310>
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,613 DEBUG Created new connection <pymysql.connections.Connection object at 0x7f20b8715520>
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,616 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> checked out from pool
(sqlalchemy.orm.path_registry): 2022-03-01 13:05:11,624 DEBUG set 'memoized_setups' on path 'EntityRegistry((<Mapper at 0x7f20b8aa0550; IdPRemoteIdsModel>,))' to '{}'
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,628 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> being returned to pool
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,629 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> rollback-on-return, via agent
(sqlalchemy.orm.path_registry): 2022-03-01 13:05:11,630 DEBUG set 'memoized_setups' on path 'EntityRegistry((<Mapper at 0x7f20b8a90af0; IdentityProviderModel>,))' to '{}'
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,631 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> checked out from pool
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,636 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> being returned to pool
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,636 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> rollback-on-return, via agent
(sqlalchemy.orm.path_registry): 2022-03-01 13:05:11,638 DEBUG set 'memoized_setups' on path 'EntityRegistry((<Mapper at 0x7f20b8a900a0; FederationProtocolModel>,))' to '{}'
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,639 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> checked out from pool
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,643 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> being returned to pool
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,643 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> rollback-on-return, via agent
(sqlalchemy.orm.path_registry): 2022-03-01 13:05:11,646 DEBUG set 'memoized_setups' on path 'EntityRegistry((<Mapper at 0x7f20b8af7be0; Service>,))' to '{}'
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,646 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> checked out from pool
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,650 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> being returned to pool
(sqlalchemy.pool.impl.QueuePool): 2022-03-01 13:05:11,650 DEBUG Connection <pymysql.connections.Connection object at 0x7f20b8715520> rollback-on-return, via agent
(keystone.server.flask.application): 2022-03-01 13:05:11,657 WARNING You are not authorized to perform the requested action.
My Juju status :
Model Controller Cloud/Region Version SLA Timestamp
kbessad-5 juju-liquid brane-liquid/default 2.9.17 unsupported 14:05:57+01:00
App Version Status Scale Charm Store Channel Rev OS Message
keycloak1 20.04 active 1 ubuntu charmstore stable 18 ubuntu
keystone 17.0.1 active 1 keystone charmstore stable 323 ubuntu Application Ready
keystone-mysql-router 8.0.28 active 1 mysql-router charmstore stable 4 ubuntu Unit is ready
keystone-saml-mellon1 17.0.1 active 1 keystone-saml-mellon charmstore stable 50 ubuntu Unit is ready
mysql-innodb-cluster 8.0.28 active 3 mysql-innodb-cluster charmstore stable 7 ubuntu Unit is ready: Mode: R/O, Cluster is ONLINE and can tolerate up to ONE failure.
openstack-dashboard 18.3.4 active 1 openstack-dashboard charmstore stable 313 ubuntu Unit is ready
openstack-dashboard-mysql-router 8.0.28 active 1 mysql-router charmstore stable 4 ubuntu Unit is ready
public-policy-routing active 2 advanced-routing charmstore stable 4 ubuntu Unit is ready
rabbitmq-server 3.8.2 active 1 rabbitmq-server charmstore stable 110 ubuntu Unit is ready
Unit Workload Agent Machine Public address Ports Message
keycloak1/1* active idle 0/lxd/7 10.140.8.45
keystone/0* active idle 0/lxd/0 10.140.8.44 5000/tcp Unit is ready
keystone-mysql-router/0* active idle 10.140.8.44 Unit is ready
keystone-saml-mellon1/0* active idle 10.140.8.44 Unit is ready
public-policy-routing/0* active idle 10.140.8.44 Unit is ready
mysql-innodb-cluster/0 active idle 0/lxd/1 10.140.8.42 Unit is ready: Mode: R/O, Cluster is ONLINE and can tolerate up to ONE failure.
mysql-innodb-cluster/1* active idle 0/lxd/2 10.140.8.43 Unit is ready: Mode: R/W, Cluster is ONLINE and can tolerate up to ONE failure.
mysql-innodb-cluster/2 active idle 0/lxd/3 10.140.8.40 Unit is ready: Mode: R/O, Cluster is ONLINE and can tolerate up to ONE failure.
openstack-dashboard/0* active idle 0/lxd/4 10.140.8.39 80/tcp,443/tcp Unit is ready
openstack-dashboard-mysql-router/0* active idle 10.140.8.39 Unit is ready
public-policy-routing/1 active idle 10.140.8.39 Unit is ready
rabbitmq-server/0* active idle 0/lxd/5 10.140.8.41 5672/tcp Unit is ready
Machine State DNS Inst id Series AZ Message
0 started 10.140.8.38 mellon-latest focal default Deployed
0/lxd/0 started 10.140.8.44 juju-00960e-0-lxd-0 focal default Container started
0/lxd/1 started 10.140.8.42 juju-00960e-0-lxd-1 focal default Container started
0/lxd/2 started 10.140.8.43 juju-00960e-0-lxd-2 focal default Container started
0/lxd/3 started 10.140.8.40 juju-00960e-0-lxd-3 focal default Container started
0/lxd/4 started 10.140.8.39 juju-00960e-0-lxd-4 focal default Container started
0/lxd/5 started 10.140.8.41 juju-00960e-0-lxd-5 focal default Container started
0/lxd/7 started 10.140.8.45 juju-00960e-0-lxd-7 focal default Container started
Any help will be welcome,
Thank you