From 47fe909d544935fe8c648c410f6b3cdb3f6216bf Mon Sep 17 00:00:00 2001 From: Georgina Date: Thu, 30 Jan 2020 13:06:30 +0000 Subject: [PATCH] Federated openid support using auth_mod_openidc This patch adds support for using mod_auth_openidc instead of shibboleth for supporting users who have a preference to use oidc for federation. A new variable called apache_mod is added to keystone_sp allowing the auth library to be selected. If left undefined shibboleth auth module will continue to be installed by default maintaining backward compatibility. This patch does not support simultaneous use of shibboleth and mod_auth_openidc primarily because shib2 depends on libcurl3 but mod_auth_openidc depends on libcurl4 which cannot coexist on Ubuntu. This can be resolved when there is a shib3 package available in a future release of Ubuntu. Change-Id: I80031f7d3f0fcc2029cd6861dcb6687e8a9f0a2e --- defaults/main.yml | 29 +++++++++++++ .../mod-auth-openidc-102bd253b677f3fc.yaml | 16 ++++++++ tasks/keystone_apache.yml | 22 +++++----- ... => keystone_federation_sp_shib_setup.yml} | 0 tasks/main.yml | 20 ++++++++- templates/keystone-httpd.conf.j2 | 41 ++++++++++++++++--- templates/keystone.conf.j2 | 10 ++--- vars/debian.yml | 8 +++- vars/redhat.yml | 3 +- vars/suse.yml | 7 +++- 10 files changed, 127 insertions(+), 29 deletions(-) create mode 100644 releasenotes/notes/mod-auth-openidc-102bd253b677f3fc.yaml rename tasks/{keystone_federation_sp_setup.yml => keystone_federation_sp_shib_setup.yml} (100%) diff --git a/defaults/main.yml b/defaults/main.yml index 88eeff69..4a0b837d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -329,6 +329,7 @@ keystone_idp: {} keystone_sp: {} #keystone_sp: # cert_duration_years: 5 +# apache_mod: shibboleth #or mod_auth_openidc # trusted_dashboard_list: # - "https://{{ external_lb_vip_address }}/auth/websso/" # - "https://{{ horizon_server_name }}/auth/websso/" @@ -425,6 +426,34 @@ keystone_sp: {} # attributes: # - name: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn' # id: upn +# +# - name: "keycloak-oidc-idp" +# oidc_provider_metadata_url: https://identity-provider/.well-known/openid-configuration +# oidc_client_id: keystone +# oidc_client_secret: secret +# oidc_crypto_passphrase: random string +# oidc_redirect_uri: https://keystone:5000/v3/OS-FEDERATION/identity_providers/keycloak-idp/protocols/openid/auth +# entity_ids: +# - 'https://identity-provider/openid-endpoint/' +# federated_identities: +# - domain: default +# project: fedproject +# group: fedgroup +# role: _member_ +# protocols: +# - name: openid +# mapping: +# name: keycloak-oidc-idp-openid-mapping +# rules: +# - remote: +# - type: OIDC-email +# local: +# - group: +# name: fedgroup +# domain: +# name: Default +# user: +# name: '{0}' keystone_service_in_ldap: false diff --git a/releasenotes/notes/mod-auth-openidc-102bd253b677f3fc.yaml b/releasenotes/notes/mod-auth-openidc-102bd253b677f3fc.yaml new file mode 100644 index 00000000..dcf27806 --- /dev/null +++ b/releasenotes/notes/mod-auth-openidc-102bd253b677f3fc.yaml @@ -0,0 +1,16 @@ +--- +features: + - Added support for using mod_auth_openidc instead of shibboleth as a + service provider for supporting users who have a preference to use OIDC + for federation. Mod_auth_openidc is the apache module that is recommended + in the keystone documentation for implementing openidc. + Added a variable to called apache_mod to keystone_sp, if left undefined + shibboleth will continue to be installed by default provided keystone_sp is + not empty. Mod_auth_openidc will not be installed unless it is spelled + correctly, any misspellings will result in a shibboleth install. + Note that installing shibboleth on Debian based metal distro deployments + may break services that depend on libcurl4, as shib2 requires libcurl3, + and they are unable to coexist. This can be resolved when there is a + shib3 package available in a future release of Ubuntu/Debian. + There is currently no support for simultaneous use of shibboleth2 and + mod_auth_openidc. diff --git a/tasks/keystone_apache.yml b/tasks/keystone_apache.yml index a9333858..fce6cbbd 100644 --- a/tasks/keystone_apache.yml +++ b/tasks/keystone_apache.yml @@ -32,6 +32,17 @@ owner: "{{ keystone_apache_default_log_owner }}" group: "{{ keystone_apache_default_log_grp }}" +- name: Place apache2 config files + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: "root" + group: "root" + with_items: "{{ keystone_apache_configs }}" + notify: + - Manage LB + - Restart web server + ## NOTE(cloudnull): ## Module enable/disable process is only functional on Debian and SUSE based systems. - name: Enable/disable apache2 modules @@ -58,17 +69,6 @@ - Manage LB - Restart web server -- name: Drop apache2 config files - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: "root" - group: "root" - with_items: "{{ keystone_apache_configs }}" - notify: - - Manage LB - - Restart web server - - name: Disable default apache site file: path: "{{ item }}" diff --git a/tasks/keystone_federation_sp_setup.yml b/tasks/keystone_federation_sp_shib_setup.yml similarity index 100% rename from tasks/keystone_federation_sp_setup.yml rename to tasks/keystone_federation_sp_shib_setup.yml diff --git a/tasks/main.yml b/tasks/main.yml index 82fa0b2d..e5e9f420 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -48,6 +48,21 @@ tags: - always +- name: Fact for apache module shibboleth to be installed + set_fact: + keystone_sp_apache_mod_shib: + "{{ (keystone_sp != {} and + (keystone_sp.apache_mod is undefined or + (keystone_sp.apache_mod is defined and keystone_sp.apache_mod != 'mod_auth_openidc')) + ) | ternary('true', 'false') }}" + +- name: Fact for apache module mod_auth_openidc to be installed + set_fact: + keystone_sp_apache_mod_auth_openidc: + "{{ (keystone_sp != {} and + keystone_sp.apache_mod is defined and keystone_sp.apache_mod == 'mod_auth_openidc') + | ternary('true', 'false') }}" + - import_tasks: db_setup.yml when: - "keystone_services['keystone-wsgi-public']['group'] in group_names" @@ -123,8 +138,9 @@ tags: - keystone-config -- import_tasks: keystone_federation_sp_setup.yml - when: keystone_sp != {} +- import_tasks: keystone_federation_sp_shib_setup.yml + when: + - keystone_sp_apache_mod_shib tags: - keystone-config diff --git a/templates/keystone-httpd.conf.j2 b/templates/keystone-httpd.conf.j2 index a75f38e3..d77895c3 100644 --- a/templates/keystone-httpd.conf.j2 +++ b/templates/keystone-httpd.conf.j2 @@ -18,7 +18,7 @@ Listen {{ keystone_service_port }} Header set Content-Security-Policy "default-src 'self' https: wss:;" {% if keystone_sp != {} -%} Header set Content-Security-Policy "script-src 'sha256-oBahlBFQem+nMs1JwgcBB03Hy8nRh5e8qEGTOcxmAuM=';" - {% endif %} + {% endif -%} Header set X-Frame-Options "{{ keystone_x_frame_options | default ('DENY') }}" {% if keystone_ssl | bool and keystone_service_internaluri_proto == "https" -%} @@ -33,9 +33,36 @@ Listen {{ keystone_service_port }} SSLHonorCipherOrder On SSLCipherSuite {{ keystone_ssl_cipher_suite }} SSLOptions +StdEnvVars +ExportCertData + {% endif -%} + {% if keystone_sp_apache_mod_auth_openidc -%} + OIDCClaimPrefix "{{ keystone_sp.trusted_idp_list.0.oidc_claim_prefix | default('OIDC-') }}" + OIDCResponseType "{{ keystone_sp.trusted_idp_list.0.oidc_resp_type | default('id_token') }}" + OIDCScope "{{ keystone_sp.trusted_idp_list.0.idc_scope | default('openid email profile') }}" + OIDCProviderMetadataURL {{ keystone_sp.trusted_idp_list.0.oidc_provider_metadata_url }} + OIDCClientID {{ keystone_sp.trusted_idp_list.0.oidc_client_id }} + OIDCClientSecret {{ keystone_sp.trusted_idp_list.0.oidc_client_secret }} + OIDCCryptoPassphrase {{ keystone_sp.trusted_idp_list.0.oidc_crypto_passphrase }} + OIDCRedirectURI {{ keystone_sp.trusted_idp_list.0.oidc_redirect_uri }} + {% if keystone_sp.trusted_idp_list.0.oidc_auth_verify_jwks_uri is defined -%} + OIDCOAuthVerifyJwksUri {{ keystone_sp.trusted_idp_list.0.oidc_auth_verify_jwks_uri }} {% endif %} - {% if keystone_sp != {} -%} + + Require valid-user + AuthType auth-openidc + + + + Require valid-user + AuthType openid-connect + + + + Require valid-user + AuthType openid-connect + + {% endif %} + {%- if keystone_sp_apache_mod_shib -%} ShibURLScheme {{ keystone_service_publicuri_proto }} @@ -57,19 +84,21 @@ Listen {{ keystone_service_port }} ShibExportAssertion Off Require valid-user - {% endif %} + {% if keystone_sp != {} -%} Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all - - {% if keystone_sp != {} -%} - ProxyPass /Shibboleth.sso ! {% endif %} + + {% if keystone_sp_apache_mod_shib -%} + ProxyPass /Shibboleth.sso ! + {% endif -%} + ProxyPass / uwsgi://127.0.0.1:{{ keystone_uwsgi_ports['keystone-wsgi-public']['socket'] }}/ diff --git a/templates/keystone.conf.j2 b/templates/keystone.conf.j2 index 5b767fab..c01c98a9 100644 --- a/templates/keystone.conf.j2 +++ b/templates/keystone.conf.j2 @@ -43,11 +43,7 @@ cache_time = {{ keystone_revocation_cache_time }} [auth] -{% if keystone_sp != {} %} -methods = {{ keystone_auth_methods }},saml2 -{% else %} -methods = {{ keystone_auth_methods }} -{% endif %} +methods = {{ keystone_auth_methods }}{% if keystone_sp_apache_mod_shib %},saml2{% endif %}{% if keystone_sp_apache_mod_auth_openidc %},openid{% endif %} {% if keystone_database_enabled | bool %} @@ -132,7 +128,11 @@ key_repository = {{ keystone_credential_key_repository }} {% if keystone_sp != {} %} [federation] +{% if keystone_sp_apache_mod_auth_openidc %} +remote_id_attribute = HTTP_OIDC_ISS +{% elif keystone_sp_apache_mod_shib %} remote_id_attribute = Shib-Identity-Provider +{% endif %} {% if keystone_sp.trusted_dashboard_list is defined %} {% for item in keystone_sp.trusted_dashboard_list %} trusted_dashboard = {{ item }} diff --git a/vars/debian.yml b/vars/debian.yml index 9aeca2eb..01811053 100644 --- a/vars/debian.yml +++ b/vars/debian.yml @@ -57,7 +57,9 @@ keystone_idp_distro_packages: - xmlsec1 keystone_sp_distro_packages: - - libapache2-mod-shib2 + - "{{ keystone_sp_apache_mod_shib | ternary('libcurl3', 'libcurl4') }}" + - "{{ keystone_sp_apache_mod_auth_openidc | ternary('libapache2-mod-auth-openidc', + 'libapache2-mod-shib2') }}" keystone_developer_mode_distro_packages: - build-essential @@ -86,7 +88,9 @@ keystone_apache_modules: - name: "ssl" state: "{{ (keystone_ssl | bool) | ternary('present', 'absent') }}" - name: "shib2" - state: "{{ ( keystone_sp != {} ) | ternary('present', 'absent') }}" + state: "{{ keystone_sp_apache_mod_shib | ternary('present', 'absent') }}" + - name: "auth_openidc" + state: "{{ keystone_sp_apache_mod_auth_openidc | ternary('present', 'absent') }}" - name: "proxy_uwsgi" state: "present" - name: "headers" diff --git a/vars/redhat.yml b/vars/redhat.yml index c15d98a4..14d7b62e 100644 --- a/vars/redhat.yml +++ b/vars/redhat.yml @@ -50,7 +50,8 @@ keystone_idp_distro_packages: - xmlsec1 keystone_sp_distro_packages: - - shibboleth + - "{{ keystone_sp_apache_mod_auth_openidc | ternary('mod_auth_openidc', + 'shibboleth') }}" keystone_developer_mode_distro_packages: - gcc diff --git a/vars/suse.yml b/vars/suse.yml index 65cea06f..e36d578f 100644 --- a/vars/suse.yml +++ b/vars/suse.yml @@ -51,7 +51,8 @@ keystone_idp_distro_packages: - xmlsec1 keystone_sp_distro_packages: - - shibboleth-sp + - "{{ keystone_sp_apache_mod_auth_openidc | ternary('apache2-mod_auth_openidc', + 'shibboleth-sp') }}" keystone_developer_mode_distro_packages: - "{{ (ansible_distribution_version is version ('42', '>=')) | ternary('patterns-openSUSE-devel_basis', 'patterns-devel-base-devel_basis') }}" @@ -85,7 +86,9 @@ keystone_apache_modules: - name: "ssl" state: "{{ (keystone_ssl | bool) | ternary('present', 'absent') }}" - name: "shib2" - state: "{{ ( keystone_sp != {} ) | ternary('present', 'absent') }}" + state: "{{ keystone_sp_apache_mod_shib | ternary('present', 'absent') }}" + - name: "auth_openidc" + state: "{{ keystone_sp_apache_mod_auth_openidc | ternary('present', 'absent') }}" - name: "proxy" state: "present" - name: "proxy_http"