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"