Merge "Add support to OpenID Connect Authentication flow"
This commit is contained in:
commit
87d8bd414d
@ -557,6 +557,7 @@ enable_glance: "{{ enable_openstack_core | bool }}"
|
||||
enable_haproxy: "yes"
|
||||
enable_keepalived: "{{ enable_haproxy | bool }}"
|
||||
enable_keystone: "{{ enable_openstack_core | bool }}"
|
||||
enable_keystone_federation: "{{ (keystone_identity_providers | length > 0) and (keystone_identity_mappings | length > 0) }}"
|
||||
enable_mariadb: "yes"
|
||||
enable_memcached: "yes"
|
||||
enable_neutron: "{{ enable_openstack_core | bool }}"
|
||||
@ -1011,6 +1012,7 @@ enable_neutron_horizon_policy_file: "{{ enable_neutron }}"
|
||||
enable_nova_horizon_policy_file: "{{ enable_nova }}"
|
||||
|
||||
horizon_internal_endpoint: "{{ internal_protocol }}://{{ kolla_internal_fqdn | put_address_in_context('url') }}:{{ horizon_tls_port if kolla_enable_tls_internal | bool else horizon_port }}"
|
||||
horizon_public_endpoint: "{{ public_protocol }}://{{ kolla_external_fqdn | put_address_in_context('url') }}:{{ horizon_tls_port if kolla_enable_tls_external | bool else horizon_port }}"
|
||||
|
||||
###################
|
||||
# External Ceph options
|
||||
@ -1158,3 +1160,45 @@ swift_public_endpoint: "{{ public_protocol }}://{{ swift_external_fqdn | put_add
|
||||
octavia_admin_endpoint: "{{ admin_protocol }}://{{ octavia_internal_fqdn | put_address_in_context('url') }}:{{ octavia_api_port }}"
|
||||
octavia_internal_endpoint: "{{ internal_protocol }}://{{ octavia_internal_fqdn | put_address_in_context('url') }}:{{ octavia_api_port }}"
|
||||
octavia_public_endpoint: "{{ public_protocol }}://{{ octavia_external_fqdn | put_address_in_context('url') }}:{{ octavia_api_port }}"
|
||||
|
||||
###################################
|
||||
# Identity federation configuration
|
||||
###################################
|
||||
# Here we configure all of the IdPs meta informations that will be required to implement identity federation with OpenStack Keystone.
|
||||
# We require the administrator to enter the following metadata:
|
||||
# * name (internal name of the IdP in Keystone);
|
||||
# * openstack_domain (the domain in Keystone that the IdP belongs to)
|
||||
# * protocol (the federated protocol used by the IdP; e.g. openid or saml);
|
||||
# * identifier (the IdP identifier; e.g. https://accounts.google.com);
|
||||
# * public_name (the public name that will be shown for users in Horizon);
|
||||
# * attribute_mapping (the attribute mapping to be used for this IdP. This mapping is configured in the "keystone_identity_mappings" configuration);
|
||||
# * metadata_folder (folder containing all the identity provider metadata as jsons named as the identifier without the protocol
|
||||
# and with '/' escaped as %2F followed with '.provider' or '.client' or '.conf'; e.g. accounts.google.com.provider; PS, all .conf,
|
||||
# .provider and .client jsons must be in the folder, even if you dont override any conf in the .conf json, you must leave it as an empty json '{}');
|
||||
# * certificate_file (the path to the Identity Provider certificate file, the file must be named as 'certificate-key-id.pem';
|
||||
# e.g. LRVweuT51StjMdsna59jKfB3xw0r8Iz1d1J1HeAbmlw.pem; You can find the key-id in the Identity provider '.well-known/openid-configuration' jwks_uri as kid);
|
||||
#
|
||||
# The IdPs meta information are to be presented to Kolla-Ansible as the following example:
|
||||
# keystone_identity_providers:
|
||||
# - name: "myidp1"
|
||||
# openstack_domain: "my-domain"
|
||||
# protocol: "openid"
|
||||
# identifier: "https://accounts.google.com"
|
||||
# public_name: "Authenticate via myidp1"
|
||||
# attribute_mapping: "mappingId1"
|
||||
# metadata_folder: "path/to/metadata/folder"
|
||||
# certificate_file: "path/to/certificate/file.pem"
|
||||
#
|
||||
# We also need to configure the attribute mapping that is used by IdPs.
|
||||
# The configuration of attribute mappings is a list of objects, where each
|
||||
# object must have a 'name' (that mapps to the 'attribute_mapping' to the IdP
|
||||
# object in the IdPs set), and the 'file' with a full qualified path to a mapping file.
|
||||
# keystone_identity_mappings:
|
||||
# - name: "mappingId1"
|
||||
# file: "/full/qualified/path/to/mapping/json/file/to/mappingId1"
|
||||
# - name: "mappingId2"
|
||||
# file: "/full/qualified/path/to/mapping/json/file/to/mappingId2"
|
||||
# - name: "mappingId3"
|
||||
# file: "/full/qualified/path/to/mapping/json/file/to/mappingId3"
|
||||
keystone_identity_providers: []
|
||||
keystone_identity_mappings: []
|
||||
|
@ -15,3 +15,5 @@ haproxy_backend_tcp_extra: []
|
||||
|
||||
haproxy_health_check: "check inter 2000 rise 2 fall 5"
|
||||
haproxy_health_check_ssl: "check check-ssl inter 2000 rise 2 fall 5"
|
||||
|
||||
haproxy_enable_federation_openid: "{{ keystone_identity_providers | selectattr('protocol','equalto','openid') | list | count > 0 }}"
|
||||
|
@ -123,7 +123,7 @@ horizon_extra_volumes: "{{ default_extra_volumes }}"
|
||||
# OpenStack
|
||||
####################
|
||||
horizon_logging_debug: "{{ openstack_logging_debug }}"
|
||||
horizon_keystone_url: "{{ keystone_internal_url }}/v3"
|
||||
horizon_keystone_url: "{{ keystone_public_url if horizon_use_keystone_public_url | bool else keystone_internal_url }}/v3"
|
||||
|
||||
|
||||
####################
|
||||
@ -149,3 +149,9 @@ horizon_murano_source_version: "{{ kolla_source_version }}"
|
||||
# TLS
|
||||
####################
|
||||
horizon_enable_tls_backend: "{{ kolla_enable_tls_backend }}"
|
||||
|
||||
# This variable was created for administrators to define which one of the Keystone's URLs should be configured in Horizon.
|
||||
# In some cases, such as when using OIDC, horizon will need to be configured with Keystone's public URL.
|
||||
# Therefore, instead of overriding the whole "horizon_keystone_url", this change allows an easier integration because
|
||||
# the Keystone public URL is already defined with variable "keystone_public_url".
|
||||
horizon_use_keystone_public_url: False
|
||||
|
@ -209,8 +209,9 @@ OPENSTACK_HOST = "{{ kolla_internal_fqdn }}"
|
||||
OPENSTACK_KEYSTONE_URL = "{{ horizon_keystone_url }}"
|
||||
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ keystone_default_user_role }}"
|
||||
|
||||
{% if enable_keystone_federation | bool %}
|
||||
# Enables keystone web single-sign-on if set to True.
|
||||
#WEBSSO_ENABLED = False
|
||||
WEBSSO_ENABLED = True
|
||||
|
||||
# Determines which authentication choice to show as default.
|
||||
#WEBSSO_INITIAL_CHOICE = "credentials"
|
||||
@ -223,13 +224,13 @@ OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ keystone_default_user_role }}"
|
||||
# Do not remove the mandatory credentials mechanism.
|
||||
# Note: The last two tuples are sample mapping keys to a identity provider
|
||||
# and federation protocol combination (WEBSSO_IDP_MAPPING).
|
||||
#WEBSSO_CHOICES = (
|
||||
# ("credentials", _("Keystone Credentials")),
|
||||
# ("oidc", _("OpenID Connect")),
|
||||
# ("saml2", _("Security Assertion Markup Language")),
|
||||
# ("acme_oidc", "ACME - OpenID Connect"),
|
||||
# ("acme_saml2", "ACME - SAML2"),
|
||||
#)
|
||||
WEBSSO_KEYSTONE_URL = "{{ keystone_public_url }}/v3"
|
||||
WEBSSO_CHOICES = (
|
||||
("credentials", _("Keystone Credentials")),
|
||||
{% for idp in keystone_identity_providers %}
|
||||
("{{ idp.name }}_{{ idp.protocol }}", "{{ idp.public_name }}"),
|
||||
{% endfor %}
|
||||
)
|
||||
|
||||
# A dictionary of specific identity provider and federation protocol
|
||||
# combinations. From the selected authentication mechanism, the value
|
||||
@ -238,10 +239,12 @@ OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ keystone_default_user_role }}"
|
||||
# specific WebSSO endpoint in keystone, otherwise it will use the value
|
||||
# as the protocol_id when redirecting to the WebSSO by protocol endpoint.
|
||||
# NOTE: The value is expected to be a tuple formatted as: (<idp_id>, <protocol_id>).
|
||||
#WEBSSO_IDP_MAPPING = {
|
||||
# "acme_oidc": ("acme", "oidc"),
|
||||
# "acme_saml2": ("acme", "saml2"),
|
||||
#}
|
||||
WEBSSO_IDP_MAPPING = {
|
||||
{% for idp in keystone_identity_providers %}
|
||||
"{{ idp.name }}_{{ idp.protocol }}": ("{{ idp.name }}", "{{ idp.protocol }}"),
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
# Disable SSL certificate checks (useful for self-signed certificates):
|
||||
#OPENSTACK_SSL_NO_VERIFY = True
|
||||
|
@ -18,6 +18,7 @@ keystone_services:
|
||||
tls_backend: "{{ keystone_enable_tls_backend }}"
|
||||
port: "{{ keystone_public_port }}"
|
||||
listen_port: "{{ keystone_public_listen_port }}"
|
||||
backend_http_extra: "{{ ['balance source'] if enable_keystone_federation | bool else [] }}"
|
||||
keystone_external:
|
||||
enabled: "{{ enable_keystone }}"
|
||||
mode: "http"
|
||||
@ -25,6 +26,7 @@ keystone_services:
|
||||
tls_backend: "{{ keystone_enable_tls_backend }}"
|
||||
port: "{{ keystone_public_port }}"
|
||||
listen_port: "{{ keystone_public_listen_port }}"
|
||||
backend_http_extra: "{{ ['balance source'] if enable_keystone_federation | bool else [] }}"
|
||||
keystone_admin:
|
||||
enabled: "{{ enable_keystone }}"
|
||||
mode: "http"
|
||||
@ -179,3 +181,23 @@ keystone_ks_services:
|
||||
# TLS
|
||||
####################
|
||||
keystone_enable_tls_backend: "{{ kolla_enable_tls_backend }}"
|
||||
|
||||
###############################
|
||||
# OpenStack identity federation
|
||||
###############################
|
||||
# Default OpenID Connect remote attribute key
|
||||
keystone_remote_id_attribute_oidc: "HTTP_OIDC_ISS"
|
||||
keystone_container_federation_oidc_metadata_folder: "{{ '/etc/apache2/metadata' if kolla_base_distro in ['debian', 'ubuntu'] else '/etc/httpd/metadata' }}"
|
||||
keystone_container_federation_oidc_idp_certificate_folder: "{{ '/etc/apache2/cert' if kolla_base_distro in ['debian', 'ubuntu'] else '/etc/httpd/cert' }}"
|
||||
keystone_container_federation_oidc_attribute_mappings_folder: "{{ container_config_directory }}/federation/oidc/attribute_maps"
|
||||
keystone_host_federation_oidc_metadata_folder: "{{ node_config_directory }}/keystone/federation/oidc/metadata"
|
||||
keystone_host_federation_oidc_idp_certificate_folder: "{{ node_config_directory }}/keystone/federation/oidc/cert"
|
||||
keystone_host_federation_oidc_attribute_mappings_folder: "{{ node_config_directory }}/keystone/federation/oidc/attribute_maps"
|
||||
|
||||
# These variables are used to define multiple trusted Horizon dashboards.
|
||||
# keystone_trusted_dashboards: ['<https://dashboardServerOne/auth/websso/>', '<https://dashboardServerTwo/auth/websso/>', '<https://dashboardServerN/auth/websso/>']
|
||||
keystone_trusted_dashboards: "{{ ['%s://%s/auth/websso/' % (public_protocol, kolla_external_fqdn), '%s/auth/websso/' % (horizon_public_endpoint)] if enable_horizon | bool else [] }}"
|
||||
keystone_enable_federation_openid: "{{ enable_keystone_federation | bool and keystone_identity_providers | selectattr('protocol','equalto','openid') | list | count > 0 }}"
|
||||
keystone_should_remove_attribute_mappings: False
|
||||
keystone_should_remove_identity_providers: False
|
||||
keystone_federation_oidc_scopes: "openid email profile"
|
||||
|
86
ansible/roles/keystone/tasks/config-federation-oidc.yml
Normal file
86
ansible/roles/keystone/tasks/config-federation-oidc.yml
Normal file
@ -0,0 +1,86 @@
|
||||
---
|
||||
- name: Remove OpenID certificate and metadata files
|
||||
become: true
|
||||
vars:
|
||||
keystone: "{{ keystone_services['keystone'] }}"
|
||||
file:
|
||||
state: absent
|
||||
path: "{{ item }}"
|
||||
when:
|
||||
- inventory_hostname in groups[keystone.group]
|
||||
with_items:
|
||||
- "{{ keystone_host_federation_oidc_metadata_folder }}"
|
||||
- "{{ keystone_host_federation_oidc_idp_certificate_folder }}"
|
||||
- "{{ keystone_host_federation_oidc_attribute_mappings_folder }}"
|
||||
|
||||
- name: Create OpenID configuration directories
|
||||
vars:
|
||||
keystone: "{{ keystone_services['keystone'] }}"
|
||||
file:
|
||||
dest: "{{ item }}"
|
||||
state: "directory"
|
||||
mode: "0770"
|
||||
become: true
|
||||
with_items:
|
||||
- "{{ keystone_host_federation_oidc_metadata_folder }}"
|
||||
- "{{ keystone_host_federation_oidc_idp_certificate_folder }}"
|
||||
- "{{ keystone_host_federation_oidc_attribute_mappings_folder }}"
|
||||
when:
|
||||
- inventory_hostname in groups[keystone.group]
|
||||
|
||||
- name: Copying OpenID Identity Providers metadata
|
||||
vars:
|
||||
keystone: "{{ keystone_services['keystone'] }}"
|
||||
become: true
|
||||
copy:
|
||||
src: "{{ item.metadata_folder }}/"
|
||||
dest: "{{ keystone_host_federation_oidc_metadata_folder }}"
|
||||
mode: "0660"
|
||||
with_items: "{{ keystone_identity_providers }}"
|
||||
when:
|
||||
- item.protocol == 'openid'
|
||||
- inventory_hostname in groups[keystone.group]
|
||||
|
||||
- name: Copying OpenID Identity Providers certificate
|
||||
vars:
|
||||
keystone: "{{ keystone_services['keystone'] }}"
|
||||
become: true
|
||||
copy:
|
||||
src: "{{ item.certificate_file }}"
|
||||
dest: "{{ keystone_host_federation_oidc_idp_certificate_folder }}"
|
||||
mode: "0660"
|
||||
with_items: "{{ keystone_identity_providers }}"
|
||||
when:
|
||||
- item.protocol == 'openid'
|
||||
- inventory_hostname in groups[keystone.group]
|
||||
|
||||
- name: Copying OpenStack Identity Providers attribute mappings
|
||||
vars:
|
||||
keystone: "{{ keystone_services['keystone'] }}"
|
||||
become: true
|
||||
copy:
|
||||
src: "{{ item.file }}"
|
||||
dest: "{{ keystone_host_federation_oidc_attribute_mappings_folder }}/{{ item.file | basename }}"
|
||||
mode: "0660"
|
||||
with_items: "{{ keystone_identity_mappings }}"
|
||||
when:
|
||||
- inventory_hostname in groups[keystone.group]
|
||||
|
||||
- name: Setting the certificates files variable
|
||||
become: true
|
||||
vars:
|
||||
keystone: "{{ keystone_services['keystone'] }}"
|
||||
find:
|
||||
path: "{{ keystone_host_federation_oidc_idp_certificate_folder }}"
|
||||
pattern: "*.pem"
|
||||
register: certificates_path
|
||||
when:
|
||||
- inventory_hostname in groups[keystone.group]
|
||||
|
||||
- name: Setting the certificates variable
|
||||
vars:
|
||||
keystone: "{{ keystone_services['keystone'] }}"
|
||||
set_fact:
|
||||
keystone_federation_openid_certificate_key_ids: "{{ certificates_path.files | map(attribute='path') | map('regex_replace', '^.*/(.*)\\.pem$', '\\1#' + keystone_container_federation_oidc_idp_certificate_folder + '/\\1.pem') | list }}" # noqa 204
|
||||
when:
|
||||
- inventory_hostname in groups[keystone.group]
|
@ -144,6 +144,10 @@
|
||||
notify:
|
||||
- Restart {{ item.key }} container
|
||||
|
||||
- include_tasks: config-federation-oidc.yml
|
||||
when:
|
||||
- keystone_enable_federation_openid | bool
|
||||
|
||||
- name: Copying over wsgi-keystone.conf
|
||||
vars:
|
||||
keystone: "{{ keystone_services.keystone }}"
|
||||
|
@ -19,3 +19,7 @@
|
||||
- import_tasks: register.yml
|
||||
|
||||
- import_tasks: check.yml
|
||||
|
||||
- include_tasks: register_identity_providers.yml
|
||||
when:
|
||||
- enable_keystone_federation | bool
|
||||
|
238
ansible/roles/keystone/tasks/register_identity_providers.yml
Normal file
238
ansible/roles/keystone/tasks/register_identity_providers.yml
Normal file
@ -0,0 +1,238 @@
|
||||
---
|
||||
- name: List configured attribute mappings (that can be used by IdPs)
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
mapping list -c ID --format value
|
||||
run_once: True
|
||||
become: True
|
||||
register: existing_mappings_register
|
||||
|
||||
- name: Register existing mappings
|
||||
set_fact:
|
||||
existing_mappings: "{{ existing_mappings_register.stdout_lines | map('trim') | list }}"
|
||||
|
||||
- name: Remove unmanaged attribute mappings
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
mapping delete {{ item }}
|
||||
run_once: True
|
||||
become: true
|
||||
with_items: "{{ existing_mappings }}"
|
||||
when:
|
||||
- item not in (keystone_identity_mappings | map(attribute='name') | list)
|
||||
- keystone_should_remove_attribute_mappings
|
||||
|
||||
- name: Create unexisting domains
|
||||
become: true
|
||||
kolla_toolbox:
|
||||
module_name: "os_keystone_domain"
|
||||
module_args:
|
||||
name: "{{ item.openstack_domain }}"
|
||||
auth: "{{ openstack_auth }}"
|
||||
endpoint_type: "{{ openstack_interface }}"
|
||||
cacert: "{{ openstack_cacert }}"
|
||||
region_name: "{{ openstack_region_name }}"
|
||||
run_once: True
|
||||
with_items: "{{ keystone_identity_providers }}"
|
||||
|
||||
- name: Register attribute mappings in OpenStack
|
||||
become: true
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
mapping create
|
||||
--rules "{{ keystone_container_federation_oidc_attribute_mappings_folder }}/{{ item.file | basename }}"
|
||||
{{ item.name }}
|
||||
run_once: True
|
||||
when:
|
||||
- item.name not in existing_mappings
|
||||
with_items: "{{ keystone_identity_mappings }}"
|
||||
|
||||
- name: Update existing attribute mappings in OpenStack
|
||||
become: true
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
mapping set
|
||||
--rules "{{ keystone_container_federation_oidc_attribute_mappings_folder }}/{{ item.file | basename }}"
|
||||
{{ item.name }}
|
||||
run_once: True
|
||||
when:
|
||||
- item.name in existing_mappings
|
||||
with_items: "{{ keystone_identity_mappings }}"
|
||||
|
||||
- name: List configured IdPs
|
||||
become: true
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
identity provider list -c ID --format value
|
||||
run_once: True
|
||||
register: existing_idps_register
|
||||
|
||||
- name: Register existing idps
|
||||
set_fact:
|
||||
existing_idps: "{{ existing_idps_register.stdout.split('\n') | map('trim') | list }}"
|
||||
|
||||
- name: Remove unmanaged identity providers
|
||||
become: true
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
identity provider delete {{ item }}
|
||||
run_once: True
|
||||
with_items: "{{ existing_idps }}"
|
||||
when:
|
||||
- item not in (keystone_identity_providers | map(attribute='name') | list)
|
||||
- keystone_should_remove_identity_providers
|
||||
|
||||
- name: Register Identity Providers in OpenStack
|
||||
become: true
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
identity provider create
|
||||
--description "{{ item.public_name }}"
|
||||
--remote-id "{{ item.identifier }}"
|
||||
--domain "{{ item.openstack_domain }}"
|
||||
{{ item.name }}
|
||||
run_once: True
|
||||
when:
|
||||
- item.name not in existing_idps
|
||||
with_items: "{{ keystone_identity_providers }}"
|
||||
|
||||
- name: Update Identity Providers in OpenStack according to Kolla-Ansible configuraitons
|
||||
become: true
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
identity provider set
|
||||
--description "{{ item.public_name }}"
|
||||
--remote-id "{{ item.identifier }}"
|
||||
"{{ item.name }}"
|
||||
run_once: True
|
||||
when:
|
||||
- item.name in existing_idps
|
||||
with_items: "{{ keystone_identity_providers }}"
|
||||
|
||||
- name: Configure attribute mappings for each Identity Provider. (We expect the mappings to be configured by the operator)
|
||||
become: true
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
federation protocol create
|
||||
--mapping {{ item.attribute_mapping }}
|
||||
--identity-provider {{ item.name }}
|
||||
{{ item.protocol }}
|
||||
run_once: True
|
||||
when:
|
||||
- item.name not in existing_idps
|
||||
with_items: "{{ keystone_identity_providers }}"
|
||||
|
||||
- name: Update attribute mappings for each Identity Provider. (We expect the mappings to be configured by the operator).
|
||||
become: true
|
||||
command: >
|
||||
docker exec -t keystone openstack
|
||||
--os-auth-url={{ openstack_auth.auth_url }}
|
||||
--os-password={{ openstack_auth.password }}
|
||||
--os-username={{ openstack_auth.username }}
|
||||
--os-project-name={{ openstack_auth.project_name }}
|
||||
--os-identity-api-version=3
|
||||
--os-interface {{ openstack_interface }}
|
||||
--os-project-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-user-domain-name {{ openstack_auth.domain_name }}
|
||||
--os-region-name {{ openstack_region_name }}
|
||||
{% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }} {% endif %}
|
||||
federation protocol set
|
||||
--identity-provider {{ item.name }}
|
||||
--mapping {{ item.attribute_mapping }}
|
||||
{{ item.protocol }}
|
||||
run_once: True
|
||||
register: result
|
||||
failed_when: result.rc not in [0, 1] # This command returns RC 1 on success, so we need to add this to avoid fails.
|
||||
when:
|
||||
- item.name in existing_idps
|
||||
with_items: "{{ keystone_identity_providers }}"
|
@ -77,3 +77,18 @@ connection_string = {{ osprofiler_backend_connection_string }}
|
||||
[cors]
|
||||
allowed_origin = {{ grafana_public_endpoint }}
|
||||
{% endif %}
|
||||
|
||||
{% if enable_keystone_federation %}
|
||||
[federation]
|
||||
{% for dashboard in keystone_trusted_dashboards %}
|
||||
trusted_dashboard = {{ dashboard }}
|
||||
{% endfor %}
|
||||
|
||||
sso_callback_template = /etc/keystone/sso_callback_template.html
|
||||
|
||||
[openid]
|
||||
remote_id_attribute = {{ keystone_remote_id_attribute_oidc }}
|
||||
|
||||
[auth]
|
||||
methods = password,token,openid,application_credential
|
||||
{% endif %}
|
||||
|
@ -1,4 +1,5 @@
|
||||
{% set keystone_dir = 'apache2/conf-enabled' if kolla_base_distro in ['ubuntu', 'debian'] else 'httpd/conf.d' %}
|
||||
{% set apache_user = 'www-data' if kolla_base_distro in ['ubuntu', 'debian'] else 'apache' %}
|
||||
{
|
||||
"command": "/usr/bin/keystone-startup.sh",
|
||||
"config_files": [
|
||||
@ -52,6 +53,22 @@
|
||||
"owner": "keystone",
|
||||
"perm": "0600"
|
||||
}{% endif %}
|
||||
{% if keystone_enable_federation_openid %},
|
||||
{
|
||||
"source": "{{ container_config_directory }}/federation/oidc/metadata",
|
||||
"dest": "{{ keystone_container_federation_oidc_metadata_folder }}",
|
||||
"owner": "{{ apache_user }}:{{ apache_user }}",
|
||||
"perm": "0600",
|
||||
"merge": true
|
||||
},
|
||||
{
|
||||
"source": "{{ container_config_directory }}/federation/oidc/cert",
|
||||
"dest": "{{ keystone_container_federation_oidc_idp_certificate_folder }}",
|
||||
"owner": "{{ apache_user }}:{{ apache_user }}",
|
||||
"perm": "0600",
|
||||
"merge": true
|
||||
}
|
||||
{% endif %}
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
@ -61,7 +78,17 @@
|
||||
{
|
||||
"path": "/var/log/kolla/keystone/keystone.log",
|
||||
"owner": "keystone:keystone"
|
||||
},{% if keystone_enable_federation_openid %}
|
||||
{
|
||||
"path": "{{ keystone_container_federation_oidc_metadata_folder }}",
|
||||
"owner": "{{ apache_user }}:{{ apache_user }}",
|
||||
"perm": "0700"
|
||||
},
|
||||
{
|
||||
"path": "{{ keystone_container_federation_oidc_idp_certificate_folder }}",
|
||||
"owner": "{{ apache_user }}:{{ apache_user }}",
|
||||
"perm": "0700"
|
||||
},{% endif %}
|
||||
{
|
||||
"path": "/etc/keystone/fernet-keys",
|
||||
"owner": "keystone:keystone",
|
||||
|
@ -51,6 +51,51 @@ LogLevel info
|
||||
SSLCertificateFile /etc/keystone/certs/keystone-cert.pem
|
||||
SSLCertificateKeyFile /etc/keystone/certs/keystone-key.pem
|
||||
{% endif %}
|
||||
|
||||
{% if keystone_enable_federation_openid %}
|
||||
OIDCClaimPrefix "OIDC-"
|
||||
OIDCClaimDelimiter ";"
|
||||
OIDCResponseType "id_token"
|
||||
OIDCScope "{{ keystone_federation_oidc_scopes }}"
|
||||
OIDCMetadataDir {{ keystone_container_federation_oidc_metadata_folder }}
|
||||
{% if keystone_federation_openid_certificate_key_ids | length > 0 %}
|
||||
OIDCOAuthVerifyCertFiles {{ keystone_federation_openid_certificate_key_ids | join(" ") }}
|
||||
{% endif %}
|
||||
OIDCCryptoPassphrase {{ keystone_federation_openid_crypto_password }}
|
||||
OIDCRedirectURI {{ keystone_public_url }}/redirect_uri
|
||||
|
||||
<Location ~ "/redirect_uri">
|
||||
Require valid-user
|
||||
AuthType openid-connect
|
||||
</Location>
|
||||
|
||||
{# WebSSO authentication endpoint -#}
|
||||
<Location /v3/auth/OS-FEDERATION/websso/openid>
|
||||
Require valid-user
|
||||
AuthType openid-connect
|
||||
</Location>
|
||||
|
||||
{% for idp in keystone_identity_providers %}
|
||||
{% if idp.protocol == 'openid' %}
|
||||
<LocationMatch /v3/auth/OS-FEDERATION/identity_providers/{{ idp.name }}/protocols/{{ idp.protocol }}/websso>
|
||||
Require valid-user
|
||||
AuthType openid-connect
|
||||
</LocationMatch>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{# CLI / API authentication endpoint -#}
|
||||
{% for idp in keystone_identity_providers %}
|
||||
{% if idp.protocol == 'openid' %}
|
||||
<LocationMatch /v3/OS-FEDERATION/identity_providers/{{ idp.name }}/protocols/{{ idp.protocol }}/auth>
|
||||
Require valid-user
|
||||
{# Note(jasonanderson): `auth-openidc` is a special auth type that can -#}
|
||||
{# additionally handle verifying bearer tokens -#}
|
||||
AuthType auth-openidc
|
||||
</LocationMatch>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:{{ keystone_admin_listen_port }}>
|
||||
|
@ -21,3 +21,4 @@ We welcome everyone to join our project!
|
||||
bug-triage
|
||||
ptl-guide
|
||||
release-management
|
||||
setup-identity-provider
|
||||
|
193
doc/source/contributor/setup-identity-provider.rst
Normal file
193
doc/source/contributor/setup-identity-provider.rst
Normal file
@ -0,0 +1,193 @@
|
||||
.. _setup-identity-provider:
|
||||
|
||||
============================
|
||||
Test Identity Provider setup
|
||||
============================
|
||||
|
||||
This guide shows how to create an Identity Provider that handles the OpenID
|
||||
Connect protocol to authenticate users when
|
||||
:keystone-doc:`using Federation with OpenStack
|
||||
</admin/federation/configure_federation.html>` (these configurations must not
|
||||
be used in a production environment).
|
||||
|
||||
Keycloak
|
||||
========
|
||||
|
||||
Keycloak is a Java application that implements an Identity Provider handling
|
||||
both OpenID Connect and SAML protocols.
|
||||
|
||||
To setup a Keycloak instance for testing is pretty simple with Docker.
|
||||
|
||||
Creating the Docker Keycloak instance
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Run the docker command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
docker run -p 8080:8080 -p 8443:8443 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:latest
|
||||
|
||||
This will create a Keycloak instance that has the admin credentials as
|
||||
admin/admin and is listening on port 8080.
|
||||
|
||||
After creating the instance, you will need to log in to the Keycloak as
|
||||
administrator and setup the first Identity Provider.
|
||||
|
||||
Creating an Identity Provider with Keycloak
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following guide assumes that the steps are executed from the same machine
|
||||
(localhost), but you can change the hostname if you want to run it from
|
||||
elsewhere.
|
||||
|
||||
In this guide, we will use the 'new_realm' as the realm name in Keycloak, so,
|
||||
if you want to use any other realm name, you must to change 'new_realm' in the
|
||||
URIs used in the guide and replace the 'new_realm' with the realm name that you
|
||||
are using.
|
||||
|
||||
- Access the admin console on http://localhost:8080/auth/ in the Administration Console option.
|
||||
- Authenticate using the credentials defined in the creation step.
|
||||
- Create a new realm in the http://localhost:8080/auth/admin/master/console/#/create/realm page.
|
||||
- After creating a realm, you will need to create a client to be used by Keystone; to do it, just access http://localhost:8080/auth/admin/master/console/#/create/client/new_realm.
|
||||
- To create a client, you will need to set the client_id (just choose anyone),
|
||||
the protocol (must be openid-connect) and the Root Url (you can leave it
|
||||
blank)
|
||||
- After creating the client, you will need to update some client's attributes
|
||||
like:
|
||||
|
||||
- Enable the Implicit flow (this one allows you to use the OpenStack CLI with
|
||||
oidcv3 plugin)
|
||||
- Set Access Type to confidential
|
||||
- Add the Horizon and Keystone URIs to the Valid Redirect URIs. Keystone should be within the '/redirect_uri' path, for example: https://horizon.com/ and https://keystone.com/redirect_uri
|
||||
- Save the changes
|
||||
- Access the client's Mappers tab to add the user's attributes that will be
|
||||
shared with the client (Keystone):
|
||||
|
||||
- In this guide, we will need the following attribute mappers in Keycloak:
|
||||
|
||||
==================================== ==============
|
||||
name/user attribute/token claim name mapper type
|
||||
==================================== ==============
|
||||
openstack-user-domain user attribute
|
||||
openstack-default-project user attribute
|
||||
==================================== ==============
|
||||
|
||||
- After creating the client, you will need to create a user in that realm to
|
||||
log in OpenStack via identity federation
|
||||
- To create a user, access http://localhost:8080/auth/admin/master/console/#/create/user/new_realm and fill the form with the user's data
|
||||
- After creating the user, you can access the tab "Credentials" to set the
|
||||
user's password
|
||||
- Then, in the tab "Attributes", you must set the authorization attributes to
|
||||
be used by Keystone, these attributes are defined in the :ref:`attribute
|
||||
mapping <attribute_mapping>` in Keystone
|
||||
|
||||
After you create the Identity provider, you will need to get some data from the
|
||||
Identity Provider to configure in Kolla-Ansible
|
||||
|
||||
Configuring Kolla Ansible to use the Identity Provider
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This section is about how one can get the data needed in
|
||||
:ref:`Setup OIDC via Kolla Ansible <setup-oidc-kolla-ansible>`.
|
||||
|
||||
- name: The realm name, in this case it will be "new_realm"
|
||||
- identifier: http://localhost:8080/auth/realms/new_realm/ (again, the "new_realm" is the name of the realm)
|
||||
- certificate_file: This one can be downloaded from http://localhost:8080/auth/admin/master/console/#/realms/new_realm/keys
|
||||
- metadata_folder:
|
||||
|
||||
- localhost%3A8080%2Fauth%2Frealms%2Fnew_realm.client:
|
||||
|
||||
- client_id: Access http://localhost:8080/auth/admin/master/console/#/realms/new_realm/clients , and access the client you created for Keystone, copy the Client ID displayed in the page
|
||||
- client_secret: In the same page you got the client_id, access the tab
|
||||
"Credentials" and copy the secret value
|
||||
- localhost%3A8080%2Fauth%2Frealms%2Fnew_realm.provider: Copy the json from http://localhost:8080/auth/realms/new_realm/.well-known/openid-configuration (the "new_realm" is the realm name)
|
||||
- localhost%3A8080%2Fauth%2Frealms%2Fnew_realm.conf: You can leave this file
|
||||
as an empty json "{}"
|
||||
|
||||
|
||||
After you finished the configuration of the Identity Provider, your main
|
||||
configuration should look something like the following:
|
||||
|
||||
.. code-block::
|
||||
|
||||
keystone_identity_providers:
|
||||
- name: "new_realm"
|
||||
openstack_domain: "new_domain"
|
||||
protocol: "openid"
|
||||
identifier: "http://localhost:8080/auth/realms/new_realm"
|
||||
public_name: "Authenticate via new_realm"
|
||||
attribute_mapping: "attribute_mapping_keycloak_new_realm"
|
||||
metadata_folder: "/root/inDev/meta-idp"
|
||||
certificate_file: "/root/inDev/certs/LRVweuT51StjMdsna59jKfB3xw0r8Iz1d1J1HeAbmlw.pem"
|
||||
keystone_identity_mappings:
|
||||
- name: "attribute_mapping_keycloak_new_realm"
|
||||
file: "/root/inDev/attr_map/attribute_mapping.json"
|
||||
|
||||
Then, after deploying OpenStack, you should be able to log in Horizon
|
||||
using the "Authenticate using" -> "Authenticate via new_realm", and writing
|
||||
"new_realm.com" in the "E-mail or domain name" field. After that, you will be
|
||||
redirected to a new page to choose the Identity Provider in Keystone. Just click in the link
|
||||
"localhost:8080/auth/realms/new_realm"; this will redirect you to Keycloak (idP) where
|
||||
you will need to log in with the user that you created. If the user's
|
||||
attributes in Keycloak are ok, the user will be created in OpenStack and you will
|
||||
be able to log in Horizon.
|
||||
|
||||
.. _attribute_mapping:
|
||||
|
||||
Attribute mapping
|
||||
~~~~~~~~~~~~~~~~~
|
||||
This section shows how to create the attribute mapping to map an Identity
|
||||
Provider user to a Keystone user (ephemeral).
|
||||
|
||||
The 'OIDC-' prefix in the remote types is defined in the 'OIDCClaimPrefix'
|
||||
configuration in the wsgi-keystone.conf file; this prefix must be in the
|
||||
attribute mapping as the mod-oidc-wsgi is adding the prefix in the user's
|
||||
attributes before sending it to Keystone. The attribute 'openstack-user-domain'
|
||||
will define the user's domain in OpenStack and the attribute
|
||||
'openstack-default-project' will define the user's project in the OpenStack
|
||||
(the user will be assigned with the role 'member' in the project)
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
[
|
||||
{
|
||||
"local": [
|
||||
{
|
||||
"user": {
|
||||
"name": "{0}",
|
||||
"email": "{1}",
|
||||
"domain": {
|
||||
"name": "{2}"
|
||||
}
|
||||
},
|
||||
"domain": {
|
||||
"name": "{2}"
|
||||
},
|
||||
"projects": [
|
||||
{
|
||||
"name": "{3}",
|
||||
"roles": [
|
||||
{
|
||||
"name": "member"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"remote": [
|
||||
{
|
||||
"type": "OIDC-preferred_username"
|
||||
},
|
||||
{
|
||||
"type": "OIDC-email"
|
||||
},
|
||||
{
|
||||
"type": "OIDC-openstack-user-domain"
|
||||
},
|
||||
{
|
||||
"type": "OIDC-openstack-default-project"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -40,3 +40,241 @@ be configured in Keystone as necessary.
|
||||
|
||||
Further infomation on Fernet tokens is available in the :keystone-doc:`Keystone
|
||||
documentation <admin/fernet-token-faq.html>`.
|
||||
|
||||
Federated identity
|
||||
------------------
|
||||
|
||||
Keystone allows users to be authenticated via identity federation. This means
|
||||
integrating OpenStack Keystone with an identity provider. The use of identity
|
||||
federation allows users to access OpenStack services without the necessity of
|
||||
an account in the OpenStack environment per se. The authentication is then
|
||||
off-loaded to the identity provider of the federation.
|
||||
|
||||
To enable identity federation, you will need to execute a set of configurations
|
||||
in multiple OpenStack systems. Therefore, it is easier to use Kolla Ansible
|
||||
to execute this process for operators.
|
||||
|
||||
For upstream documentations, please see
|
||||
:keystone-doc:`Configuring Keystone for Federation
|
||||
<admin/federation/configure_federation.html>`
|
||||
|
||||
Supported protocols
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
OpenStack supports both OpenID Connect and SAML protocols for federated
|
||||
identity, but for now, kolla Ansible supports only OpenID Connect.
|
||||
Therefore, if you desire to use SAML in your environment, you will need
|
||||
to set it up manually or extend Kolla Ansible to also support it.
|
||||
|
||||
.. _setup-oidc-kolla-ansible:
|
||||
|
||||
Setting up OpenID Connect via Kolla Ansible
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First, you will need to register the OpenStack (Keystone) in your Identity
|
||||
provider as a Service Provider.
|
||||
|
||||
After registering Keystone, you will need to add the Identity Provider
|
||||
configurations in your kolla-ansible globals configuration as the example
|
||||
below:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
keystone_identity_providers:
|
||||
- name: "myidp1"
|
||||
openstack_domain: "my-domain"
|
||||
protocol: "openid"
|
||||
identifier: "https://accounts.google.com"
|
||||
public_name: "Authenticate via myidp1"
|
||||
attribute_mapping: "mappingId1"
|
||||
metadata_folder: "path/to/metadata/folder"
|
||||
certificate_file: "path/to/certificate/file.pem"
|
||||
|
||||
keystone_identity_mappings:
|
||||
- name: "mappingId1"
|
||||
file: "/full/qualified/path/to/mapping/json/file/to/mappingId1"
|
||||
|
||||
Identity providers configurations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
name
|
||||
****
|
||||
|
||||
The internal name of the Identity provider in OpenStack.
|
||||
|
||||
openstack_domain
|
||||
****************
|
||||
|
||||
The OpenStack domain that the Identity Provider belongs.
|
||||
|
||||
protocol
|
||||
********
|
||||
|
||||
The federated protocol used by the IdP; e.g. openid or saml. We support only
|
||||
OpenID connect right now.
|
||||
|
||||
identifier
|
||||
**********
|
||||
|
||||
The Identity provider URL; e.g. https://accounts.google.com .
|
||||
|
||||
public_name
|
||||
***********
|
||||
|
||||
The Identity provider public name that will be shown for users in the Horizon
|
||||
login page.
|
||||
|
||||
attribute_mapping
|
||||
*****************
|
||||
|
||||
The attribute mapping to be used for the Identity Provider. This mapping is
|
||||
expected to already exist in OpenStack or be configured in the
|
||||
`keystone_identity_mappings` property.
|
||||
|
||||
metadata_folder
|
||||
***************
|
||||
|
||||
Path to the folder containing all of the identity provider metadata as JSON
|
||||
files.
|
||||
|
||||
The metadata folder must have all your Identity Providers configurations,
|
||||
the name of the files will be the name (with path) of the Issuer configuration.
|
||||
Such as:
|
||||
|
||||
.. code-block::
|
||||
|
||||
- <IDP metadata directory>
|
||||
- keycloak.example.org%2Fauth%2Frealms%2Fidp.client
|
||||
|
|
||||
- keycloak.example.org%2Fauth%2Frealms%2Fidp.conf
|
||||
|
|
||||
- keycloak.example.org%2Fauth%2Frealms%2Fidp.provider
|
||||
|
||||
.. note::
|
||||
|
||||
The name of the file must be URL-encoded if needed. For example, if you have
|
||||
an Issuer with ``/`` in the URL, then you need to escape it to ``%2F`` by
|
||||
applying a URL escape in the file name.
|
||||
|
||||
The content of these files must be a JSON
|
||||
|
||||
``client``:
|
||||
|
||||
The ``.client`` file handles the Service Provider credentials in the Issuer.
|
||||
|
||||
During the first step, when you registered the OpenStack as a
|
||||
Service Provider in the Identity Provider, you submitted a `cliend_id` and
|
||||
generated a `client_secret`, so these are the values you must use in this
|
||||
JSON file.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"client_id":"<openid_client_id>",
|
||||
"client_secret":"<openid_client_secret>"
|
||||
}
|
||||
|
||||
``conf``:
|
||||
|
||||
This file will be a JSON that overrides some of the OpenID Connect options. The
|
||||
options that can be overridden are listed in the
|
||||
`OpenID Connect Apache2 plugin documentation`_.
|
||||
.. _`OpenID Connect Apache2 plugin documentation`: https://github.com/zmartzone/mod_auth_openidc/wiki/Multiple-Providers#opclient-configuration
|
||||
|
||||
If you do not want to override the config values, you can leave this file as
|
||||
an empty JSON file such as ``{}``.
|
||||
|
||||
``provider``:
|
||||
|
||||
This file will contain all specifications about the IdentityProvider. To
|
||||
simplify, you can just use the JSON returned in the ``.well-known``
|
||||
Identity provider's endpoint:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"issuer": "https://accounts.google.com",
|
||||
"authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
"token_endpoint": "https://oauth2.googleapis.com/token",
|
||||
"userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
|
||||
"revocation_endpoint": "https://oauth2.googleapis.com/revoke",
|
||||
"jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
|
||||
"response_types_supported": [
|
||||
"code",
|
||||
"token",
|
||||
"id_token",
|
||||
"code token",
|
||||
"code id_token",
|
||||
"token id_token",
|
||||
"code token id_token",
|
||||
"none"
|
||||
],
|
||||
"subject_types_supported": [
|
||||
"public"
|
||||
],
|
||||
"id_token_signing_alg_values_supported": [
|
||||
"RS256"
|
||||
],
|
||||
"scopes_supported": [
|
||||
"openid",
|
||||
"email",
|
||||
"profile"
|
||||
],
|
||||
"token_endpoint_auth_methods_supported": [
|
||||
"client_secret_post",
|
||||
"client_secret_basic"
|
||||
],
|
||||
"claims_supported": [
|
||||
"aud",
|
||||
"email",
|
||||
"email_verified",
|
||||
"exp",
|
||||
"family_name",
|
||||
"given_name",
|
||||
"iat",
|
||||
"iss",
|
||||
"locale",
|
||||
"name",
|
||||
"picture",
|
||||
"sub"
|
||||
],
|
||||
"code_challenge_methods_supported": [
|
||||
"plain",
|
||||
"S256"
|
||||
]
|
||||
}
|
||||
|
||||
certificate_file
|
||||
****************
|
||||
|
||||
Path to the Identity Provider certificate file, the file must be named as
|
||||
'certificate-key-id.pem'. E.g.
|
||||
|
||||
.. code-block::
|
||||
|
||||
- fb8ca5b7d8d9a5c6c6788071e866c6c40f3fc1f9.pem
|
||||
|
||||
You can find the key-id in the Identity provider
|
||||
`.well-known/openid-configuration` `jwks_uri` like in
|
||||
`https://www.googleapis.com/oauth2/v3/certs` :
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"e": "AQAB",
|
||||
"use": "sig",
|
||||
"n": "zK8PHf_6V3G5rU-viUOL1HvAYn7q--dxMoU...",
|
||||
"kty": "RSA",
|
||||
"kid": "fb8ca5b7d8d9a5c6c6788071e866c6c40f3fc1f9",
|
||||
"alg": "RS256"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
The public key is different from the certificate, the file in this
|
||||
configuration must be the Identity provider's certificate and not the
|
||||
Identity provider's public key.
|
||||
|
@ -252,3 +252,8 @@ redis_master_password:
|
||||
####################
|
||||
prometheus_mysql_exporter_database_password:
|
||||
prometheus_alertmanager_password:
|
||||
|
||||
###############################
|
||||
# OpenStack identity federation
|
||||
###############################
|
||||
keystone_federation_openid_crypto_password:
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add support for the OpenID Connect authentication protocol in Keystone and
|
||||
enables both ID and access token authentication flows.
|
Loading…
Reference in New Issue
Block a user