Keystone Federation Service Provider Configuration
This patch adds the ability to configure Keystone as a Service Provider (SP) for a Federated Identity Provider (IdP). * New variables to configure Keystone as a service provider are now supported under a root `keystone_sp` variable. Example configurations can be seen in Keystone's defaults file. This configuration includes the list of identity providers and trusted dashboards. (At this time only one identity provider is supported). * Identity provider configuration includes the remote-to-local user mapping and the list of remote attributes the SP can obtain from the IdP. * Shibboleth is installed and configured in the Keystone containers when SP configuration is present. * Horizon is configured for SSO login DocImpact UpgradeImpact Implements: blueprint keystone-federation Change-Id: I78b3d740434ea4b3ca0bd9f144e4a07026be23c6 Co-Authored-By: Jesse Pretorius <jesse.pretorius@rackspace.co.uk>
This commit is contained in:
parent
ef8e0fc5cd
commit
17ac571e7a
@ -120,7 +120,7 @@ keystone_service_internalurl: "{{ keystone_service_internalurl_v3 }}"
|
||||
keystone_service_adminurl: "{{ keystone_service_adminurl_v3 }}"
|
||||
|
||||
## Set this value to override the "public_endpoint" keystone.conf variable
|
||||
#keystone_public_endpoint:
|
||||
#keystone_public_endpoint: "{{ keystone_service_publicuri }}"
|
||||
|
||||
## Apache setup
|
||||
keystone_apache_log_level: info
|
||||
@ -190,6 +190,82 @@ keystone_recreate_keys: False
|
||||
# contact_telephone: 555-55-5555
|
||||
# contact_type: technical
|
||||
|
||||
# Enable the following section in order to install and configure
|
||||
# Keystone as a Resource Service Provider (SP) and to configure
|
||||
# trusts with specific Identity Providers (IdP).
|
||||
#keystone_sp:
|
||||
# cert_duration_years: 5
|
||||
# trusted_dashboard_list:
|
||||
# - "https://{{ external_lb_vip_address }}/auth/websso/"
|
||||
# trusted_idp_list:
|
||||
# note that only one of these is supported at any one time for now
|
||||
# - name: "keystone-idp"
|
||||
# entity_ids:
|
||||
# - 'https://keystone-idp:5000/v3/OS-FEDERATION/saml2/idp'
|
||||
# metadata_uri: 'https://keystone-idp:5000/v3/OS-FEDERATION/saml2/metadata'
|
||||
# metadata_file: 'metadata-keystone-idp.xml'
|
||||
# metadata_reload: 1800
|
||||
# federated_identities:
|
||||
# - domain: Default
|
||||
# project: fedproject
|
||||
# group: fedgroup
|
||||
# role: _member_
|
||||
# protocols:
|
||||
# - name: saml2
|
||||
# mapping:
|
||||
# name: keystone-idp-mapping
|
||||
# rules:
|
||||
# - remote:
|
||||
# - type: openstack_user
|
||||
# local:
|
||||
# - group:
|
||||
# name: fedgroup
|
||||
# domain:
|
||||
# name: Default
|
||||
# user:
|
||||
# name: '{0}'
|
||||
# attributes:
|
||||
# - name: openstack_user
|
||||
# id: openstack_user
|
||||
# - name: openstack_roles
|
||||
# id: openstack_roles
|
||||
# - name: openstack_project
|
||||
# id: openstack_project
|
||||
# - name: openstack_user_domain
|
||||
# id: openstack_user_domain
|
||||
# - name: openstack_project_domain
|
||||
# id: openstack_project_domain
|
||||
#
|
||||
# - name: 'testshib-idp'
|
||||
# entity_ids:
|
||||
# - 'https://idp.testshib.org/idp/shibboleth'
|
||||
# metadata_uri: 'http://www.testshib.org/metadata/testshib-providers.xml'
|
||||
# metadata_file: 'metadata-testshib-idp.xml'
|
||||
# metadata_reload: 1800
|
||||
# federated_identities:
|
||||
# - domain: Default
|
||||
# project: fedproject
|
||||
# group: fedgroup
|
||||
# role: _member_
|
||||
# protocols:
|
||||
# - name: saml2
|
||||
# mapping:
|
||||
# name: testshib-idp-mapping
|
||||
# rules:
|
||||
# - remote:
|
||||
# - type: eppn
|
||||
# local:
|
||||
# - group:
|
||||
# name: fedgroup
|
||||
# domain:
|
||||
# name: Default
|
||||
# - user:
|
||||
# name: '{0}'
|
||||
|
||||
# Keystone Federation SP Packages
|
||||
keystone_sp_apt_packages:
|
||||
- libapache2-mod-shib2
|
||||
|
||||
# Common apt packages
|
||||
keystone_apt_packages:
|
||||
- apache2
|
||||
|
22
files/sso_callback_template.html
Normal file
22
files/sso_callback_template.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Keystone WebSSO redirect</title>
|
||||
</head>
|
||||
<body>
|
||||
<form id="sso" name="sso" action="$host" method="post">
|
||||
Please wait...
|
||||
<br/>
|
||||
<input type="hidden" name="token" id="token" value="$token"/>
|
||||
<noscript>
|
||||
<input type="submit" name="submit_no_javascript" id="submit_no_javascript"
|
||||
value="If your JavaScript is disabled, please click to continue"/>
|
||||
</noscript>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
window.onload = function() {
|
||||
document.forms['sso'].submit();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -22,3 +22,13 @@
|
||||
until: apache_restart|success
|
||||
retries: 5
|
||||
delay: 2
|
||||
|
||||
- name: Restart Shibd
|
||||
service:
|
||||
name: "shibd"
|
||||
state: "restarted"
|
||||
pattern: "shibd"
|
||||
register: shibd_restart
|
||||
until: shibd_restart|success
|
||||
retries: 5
|
||||
delay: 2
|
||||
|
117
library/keystone_sp
Normal file
117
library/keystone_sp
Normal file
@ -0,0 +1,117 @@
|
||||
#!/usr/bin/python
|
||||
# (c) 2015, Kevin Carter <kevin.carter@rackspace.com>
|
||||
#
|
||||
# Copyright 2015, Rackspace US, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: keystone_sp
|
||||
version_added: "1.9.2"
|
||||
short_description:
|
||||
- Creates a fact for keystone_federated_identities and keystone_protocols
|
||||
description:
|
||||
- Sets facts called `keystone_federated_identities` and
|
||||
`keystone_federated_protocols`, which are lists of hashes built from
|
||||
keystone_sp using the information in the `federated_identities` and
|
||||
`protocols` keys.
|
||||
options:
|
||||
sp_data:
|
||||
description:
|
||||
- Hash to build the service provider lists from
|
||||
required: true
|
||||
author: Kevin Carter
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Set the keystone_federated_identities and keystone_federated_protocols facts
|
||||
- keystone_sp:
|
||||
sp_data: "{{ keystone_sp }}"
|
||||
when: keystone_sp is defined
|
||||
"""
|
||||
|
||||
# Keystone service provider data structure example.
|
||||
"""
|
||||
keystone_sp:
|
||||
trusted_idp_list:
|
||||
- name: "keystone-idp"
|
||||
federated_identities:
|
||||
- domain: Default
|
||||
project: fedproject
|
||||
group: fedgroup
|
||||
role: _member_
|
||||
protocols:
|
||||
- name: saml2
|
||||
mapping:
|
||||
...
|
||||
- name: 'testshib-idp'
|
||||
federated_identities:
|
||||
- domain: Default
|
||||
project: fedproject2
|
||||
group: fedgroup2
|
||||
role: _member_
|
||||
protocols:
|
||||
- name: saml2
|
||||
mapping:
|
||||
...
|
||||
"""
|
||||
|
||||
|
||||
class KeystoneSp(object):
|
||||
def __init__(self, module):
|
||||
"""Generate an integer from a name."""
|
||||
self.module = module
|
||||
self.identities_return_list = list()
|
||||
self.protocols_return_list = list()
|
||||
self.sp_data = self.module.params['sp_data']
|
||||
|
||||
def populate_sp_data(self):
|
||||
trusted_idp_list = self.sp_data['trusted_idp_list']
|
||||
for trusted_idp in trusted_idp_list:
|
||||
federated_identities = trusted_idp.get('federated_identities')
|
||||
if federated_identities:
|
||||
self.identities_return_list.extend(federated_identities)
|
||||
protocols = trusted_idp.get('protocols')
|
||||
if protocols:
|
||||
for protocol in protocols:
|
||||
self.protocols_return_list.append(
|
||||
{'idp': trusted_idp, 'protocol': protocol})
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
sp_data=dict(
|
||||
required=True
|
||||
)
|
||||
),
|
||||
supports_check_mode=False
|
||||
)
|
||||
try:
|
||||
ksp = KeystoneSp(module=module)
|
||||
ksp.populate_sp_data()
|
||||
module.exit_json(
|
||||
changed=True,
|
||||
ansible_facts={
|
||||
'keystone_federated_identities': ksp.identities_return_list,
|
||||
'keystone_federated_protocols': ksp.protocols_return_list}
|
||||
)
|
||||
except Exception as exp:
|
||||
resp = {'stderr': exp}
|
||||
module.fail_json(msg='Failed Process', **resp)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -61,5 +61,17 @@
|
||||
apache2_module:
|
||||
name: ssl
|
||||
state: "{{ (keystone_ssl_enabled | bool) | ternary('present', 'absent') }}"
|
||||
notify:
|
||||
- Restart Apache
|
||||
tags:
|
||||
- keystone-httpd
|
||||
|
||||
- name: Enable/disable mod_shib2 for apache2
|
||||
apache2_module:
|
||||
name: shib2
|
||||
state: "{{ ( keystone_sp is defined ) | ternary('present', 'absent') }}"
|
||||
ignore_errors: yes
|
||||
notify:
|
||||
- Restart Apache
|
||||
tags:
|
||||
- keystone-httpd
|
||||
|
152
tasks/keystone_federation_sp_idp_setup.yml
Normal file
152
tasks/keystone_federation_sp_idp_setup.yml
Normal file
@ -0,0 +1,152 @@
|
||||
---
|
||||
# Copyright 2014, Rackspace US, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# note that these tasks will run when the id/name parameter is present.
|
||||
# Providing the id/name without the other required params is a user error.
|
||||
|
||||
# TODO: Revisit this method when Ansible 2 releases
|
||||
# User with_subelements instead, but in v1.x it's broken
|
||||
- name: Set keystone_federated_identities fact
|
||||
keystone_sp:
|
||||
sp_data: "{{ keystone_sp }}"
|
||||
tags:
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Ensure domain which remote IDP users are mapped onto exists
|
||||
keystone:
|
||||
command: ensure_domain
|
||||
domain_name: "{{ item.domain }}"
|
||||
token: "{{ keystone_auth_admin_token }}"
|
||||
endpoint: "{{ keystone_service_adminurl }}"
|
||||
insecure: "{{ keystone_service_adminuri_insecure }}"
|
||||
when: item.domain is defined
|
||||
with_items: keystone_federated_identities
|
||||
tags:
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Ensure project which remote IDP users are mapped onto exists
|
||||
keystone:
|
||||
command: ensure_project
|
||||
project_name: "{{ item.project }}"
|
||||
domain_name: "{{ item.domain | default('Default') }}"
|
||||
token: "{{ keystone_auth_admin_token }}"
|
||||
endpoint: "{{ keystone_service_adminurl }}"
|
||||
insecure: "{{ keystone_service_adminuri_insecure }}"
|
||||
when: item.project is defined
|
||||
with_items: keystone_federated_identities
|
||||
tags:
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Ensure user which remote IDP users are mapped onto exists
|
||||
keystone:
|
||||
command: ensure_user
|
||||
user_name: "{{ item.user }}"
|
||||
password: "{{ item.password }}"
|
||||
project_name: "{{ item.project }}"
|
||||
domain_name: "{{ item.domain | default('Default') }}"
|
||||
token: "{{ keystone_auth_admin_token }}"
|
||||
endpoint: "{{ keystone_service_adminurl }}"
|
||||
insecure: "{{ keystone_service_adminuri_insecure }}"
|
||||
when: >
|
||||
item.user is defined and
|
||||
item.password is defined and
|
||||
item.project is defined
|
||||
with_items: keystone_federated_identities
|
||||
tags:
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Ensure Group for external IDP users exists
|
||||
keystone:
|
||||
command: ensure_group
|
||||
group_name: "{{ item.group }}"
|
||||
domain_name: "{{ item.domain | default('Default') }}"
|
||||
token: "{{ keystone_auth_admin_token }}"
|
||||
endpoint: "{{ keystone_service_adminurl }}"
|
||||
insecure: "{{ keystone_service_adminuri_insecure }}"
|
||||
when: item.group is defined
|
||||
with_items: keystone_federated_identities
|
||||
tags:
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Ensure Role for external IDP users exists
|
||||
keystone:
|
||||
command: "ensure_role"
|
||||
role_name: "{{ item.role | default('_member_') }}"
|
||||
token: "{{ keystone_auth_admin_token }}"
|
||||
endpoint: "{{ keystone_service_adminurl }}"
|
||||
insecure: "{{ keystone_service_adminuri_insecure }}"
|
||||
when: >
|
||||
item.group is defined and
|
||||
item.project is defined
|
||||
with_items: keystone_federated_identities
|
||||
tags:
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Ensure Group/Project/Role mapping exists
|
||||
keystone:
|
||||
command: ensure_group_role
|
||||
group_name: "{{ item.group }}"
|
||||
project_name: "{{ item.project }}"
|
||||
role_name: "{{ item.role | default('_member_') }}"
|
||||
token: "{{ keystone_auth_admin_token }}"
|
||||
endpoint: "{{ keystone_service_adminurl }}"
|
||||
insecure: "{{ keystone_service_adminuri_insecure }}"
|
||||
when: >
|
||||
item.group is defined and
|
||||
item.project is defined
|
||||
with_items: keystone_federated_identities
|
||||
tags:
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Ensure mapping for external IDP attributes exists
|
||||
keystone:
|
||||
command: ensure_mapping
|
||||
mapping_name: "{{ item.protocol.mapping.name }}"
|
||||
mapping_rules: "{{ item.protocol.mapping.rules }}"
|
||||
token: "{{ keystone_auth_admin_token }}"
|
||||
endpoint: "{{ keystone_service_adminurl }}"
|
||||
insecure: "{{ keystone_service_adminuri_insecure }}"
|
||||
when: item.protocol.mapping.name is defined
|
||||
with_items: keystone_federated_protocols
|
||||
tags:
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Ensure external IDP
|
||||
keystone:
|
||||
command: ensure_identity_provider
|
||||
idp_name: "{{ item.name }}"
|
||||
idp_remote_ids: "{{ item.entity_ids }}"
|
||||
idp_enabled: true
|
||||
token: "{{ keystone_auth_admin_token }}"
|
||||
endpoint: "{{ keystone_service_adminurl }}"
|
||||
insecure: "{{ keystone_service_adminuri_insecure }}"
|
||||
when: item.name is defined
|
||||
with_items: keystone_sp.trusted_idp_list
|
||||
tags:
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Ensure federation protocol exists
|
||||
keystone:
|
||||
command: ensure_protocol
|
||||
protocol_name: "{{ item.protocol.name }}"
|
||||
idp_name: "{{ item.idp.name }}"
|
||||
mapping_name: "{{ item.protocol.mapping.name }}"
|
||||
token: "{{ keystone_auth_admin_token }}"
|
||||
endpoint: "{{ keystone_service_adminurl }}"
|
||||
insecure: "{{ keystone_service_adminuri_insecure }}"
|
||||
when: item.protocol.name is defined
|
||||
with_items: keystone_federated_protocols
|
||||
tags:
|
||||
- keystone-federation-sp
|
101
tasks/keystone_federation_sp_setup.yml
Normal file
101
tasks/keystone_federation_sp_setup.yml
Normal file
@ -0,0 +1,101 @@
|
||||
---
|
||||
# Copyright 2015, Rackspace US, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- name: Drop Shibboleth Config
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
owner: "{{ keystone_system_user_name }}"
|
||||
group: "{{ keystone_system_group_name }}"
|
||||
mode: "{{ item.mode|default('0644') }}"
|
||||
with_items:
|
||||
- { src: "shibboleth-attribute-map.xml.j2", dest: "/etc/shibboleth/attribute-map.xml" }
|
||||
- { src: "shibboleth2.xml.j2", dest: "/etc/shibboleth/shibboleth2.xml" }
|
||||
notify:
|
||||
- Restart Shibd
|
||||
tags:
|
||||
- keystone-config
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Generate the Shibboleth SP key-pair
|
||||
shell: "shib-keygen -h {{ external_lb_vip_address }} -y {{ keystone_sp.cert_duration_years }}"
|
||||
args:
|
||||
creates: "/etc/shibboleth/sp-cert.pem"
|
||||
when: inventory_hostname == groups['keystone_all'][0]
|
||||
notify:
|
||||
- Restart Apache
|
||||
- Restart Shibd
|
||||
tags:
|
||||
- keystone-config
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Store Shibboleth SP key-pair
|
||||
memcached:
|
||||
name: "{{ item.name }}"
|
||||
file_path: "{{ item.src }}"
|
||||
state: "present"
|
||||
server: "{{ memcached_servers }}"
|
||||
encrypt_string: "{{ memcached_encryption_key }}"
|
||||
with_items:
|
||||
- { src: "/etc/shibboleth/sp-cert.pem", name: "keystone_sp_cert" }
|
||||
- { src: "/etc/shibboleth/sp-key.pem", name: "keystone_sp_key" }
|
||||
register: memcache_keys
|
||||
until: memcache_keys|success
|
||||
retries: 5
|
||||
delay: 2
|
||||
when: inventory_hostname == groups['keystone_all'][0]
|
||||
tags:
|
||||
- keystone-config
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Distribute the Shibboleth SP key-pair
|
||||
memcached:
|
||||
name: "{{ item.name }}"
|
||||
file_path: "{{ item.src }}"
|
||||
state: "retrieve"
|
||||
file_mode: "{{ item.file_mode }}"
|
||||
dir_mode: "{{ item.dir_mode }}"
|
||||
server: "{{ memcached_servers }}"
|
||||
encrypt_string: "{{ memcached_encryption_key }}"
|
||||
with_items:
|
||||
- { src: "/etc/shibboleth/sp-cert.pem", name: "keystone_sp_cert", file_mode: "0640", dir_mode: "0750" }
|
||||
- { src: "/etc/shibboleth/sp-key.pem", name: "keystone_sp_key", file_mode: "0600", dir_mode: "0750" }
|
||||
register: memcache_keys
|
||||
until: memcache_keys|success
|
||||
retries: 5
|
||||
delay: 2
|
||||
when: inventory_hostname != groups['keystone_all'][0]
|
||||
notify:
|
||||
- Restart Apache
|
||||
- Restart Shibd
|
||||
tags:
|
||||
- keystone-config
|
||||
- keystone-federation-sp
|
||||
|
||||
- name: Set appropriate file ownership on the Shibboleth SP key-pair
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
owner: "_shibd"
|
||||
group: "_shibd"
|
||||
with_items:
|
||||
- "/etc/shibboleth/sp-cert.pem"
|
||||
- "/etc/shibboleth/sp-key.pem"
|
||||
when: inventory_hostname != groups['keystone_all'][0]
|
||||
notify:
|
||||
- Restart Apache
|
||||
- Restart Shibd
|
||||
tags:
|
||||
- keystone-config
|
||||
- keystone-federation-sp
|
@ -49,6 +49,19 @@
|
||||
tags:
|
||||
- keystone-apt-packages
|
||||
|
||||
- name: Install SP apt packages
|
||||
apt:
|
||||
pkg: "{{ item }}"
|
||||
state: latest
|
||||
register: install_packages
|
||||
until: install_packages|success
|
||||
retries: 5
|
||||
delay: 2
|
||||
with_items: keystone_sp_apt_packages
|
||||
when: keystone_sp is defined
|
||||
tags:
|
||||
- keystone-apt-packages
|
||||
|
||||
- name: Install pip packages
|
||||
pip:
|
||||
name: "{{ item }}"
|
||||
|
@ -36,6 +36,7 @@
|
||||
mode: "{{ item.mode|default('0644') }}"
|
||||
with_items:
|
||||
- { src: "keystone-paste.ini", dest: "/etc/keystone/keystone-paste.ini" }
|
||||
- { src: "sso_callback_template.html", dest: "/etc/keystone/sso_callback_template.html" }
|
||||
- { src: "keystone-wsgi.py", dest: "/var/www/cgi-bin/keystone/admin", mode: "0755" }
|
||||
- { src: "keystone-wsgi.py", dest: "/var/www/cgi-bin/keystone/main", mode: "0755" }
|
||||
notify:
|
||||
|
@ -29,6 +29,10 @@
|
||||
|
||||
- include: keystone_post_install.yml
|
||||
|
||||
- include: keystone_federation_sp_setup.yml
|
||||
when: >
|
||||
keystone_sp is defined
|
||||
|
||||
- include: keystone_db_setup.yml
|
||||
when: >
|
||||
inventory_hostname == groups['keystone_all'][0]
|
||||
@ -40,6 +44,11 @@
|
||||
when: >
|
||||
inventory_hostname == groups['keystone_all'][0]
|
||||
|
||||
- include: keystone_federation_sp_idp_setup.yml
|
||||
when: >
|
||||
keystone_sp is defined and
|
||||
inventory_hostname == groups['keystone_all'][0]
|
||||
|
||||
- name: Flush handlers
|
||||
meta: flush_handlers
|
||||
|
||||
|
@ -25,6 +25,32 @@ WSGIDaemonProcess keystone user={{ keystone_system_user_name }} group=nogroup pr
|
||||
SSLOptions +StdEnvVars +ExportCertData
|
||||
{% endif %}
|
||||
|
||||
{% if keystone_sp is defined -%}
|
||||
ShibURLScheme {{ keystone_service_publicuri_proto }}
|
||||
|
||||
<Location /Shibboleth.sso>
|
||||
SetHandler shib
|
||||
</Location>
|
||||
|
||||
<Location /v3/auth/OS-FEDERATION/websso/saml2>
|
||||
AuthType shibboleth
|
||||
ShibRequestSetting requireSession 1
|
||||
ShibRequestSetting exportAssertion 1
|
||||
ShibRequireSession On
|
||||
ShibExportAssertion On
|
||||
Require valid-user
|
||||
</Location>
|
||||
|
||||
<LocationMatch /v3/OS-FEDERATION/identity_providers/.*?/protocols/saml2/auth>
|
||||
ShibRequestSetting requireSession 1
|
||||
AuthType shibboleth
|
||||
ShibExportAssertion Off
|
||||
Require valid-user
|
||||
</LocationMatch>
|
||||
|
||||
WSGIScriptAliasMatch ^(/v3/OS-FEDERATION/identity_providers/.*?/protocols/.*?/auth)$ /var/www/cgi-bin/keystone/main/$1
|
||||
{%- endif %}
|
||||
|
||||
WSGIScriptAlias / /var/www/cgi-bin/keystone/main
|
||||
WSGIProcessGroup keystone
|
||||
</VirtualHost>
|
||||
|
@ -43,8 +43,12 @@ cache_time = {{ keystone_revocation_cache_time }}
|
||||
|
||||
|
||||
[auth]
|
||||
{% if keystone_sp is defined %}
|
||||
methods = {{ keystone_auth_methods }},saml2
|
||||
saml2 = keystone.auth.plugins.mapped.Mapped
|
||||
{% else %}
|
||||
methods = {{ keystone_auth_methods }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
[database]
|
||||
connection = mysql://{{ keystone_galera_user }}:{{ keystone_container_mysql_password }}@{{ keystone_galera_address }}/{{ keystone_galera_database }}?charset=utf8
|
||||
@ -132,3 +136,13 @@ public_port = {{ keystone_service_port }}
|
||||
rabbit_hosts = {{ rabbitmq_servers }}
|
||||
rabbit_userid = {{ rabbitmq_userid }}
|
||||
rabbit_password = {{ rabbitmq_password }}
|
||||
|
||||
{% if keystone_sp is defined %}
|
||||
[federation]
|
||||
remote_id_attribute = Shib-Identity-Provider
|
||||
{% if keystone_sp.trusted_dashboard_list is defined %}
|
||||
{% for item in keystone_sp.trusted_dashboard_list %}
|
||||
trusted_dashboard = {{ item }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
63
templates/shibboleth-attribute-map.xml.j2
Normal file
63
templates/shibboleth-attribute-map.xml.j2
Normal file
@ -0,0 +1,63 @@
|
||||
<Attributes xmlns="urn:mace:shibboleth:2.0:attribute-map"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<!--
|
||||
The below default attributes are standard for a Shibboleth
|
||||
Identity Provider and will likely work with many other
|
||||
standard SAML2 Identity Providers.
|
||||
-->
|
||||
|
||||
<Attribute name="urn:mace:dir:attribute-def:eduPersonPrincipalName" id="eppn">
|
||||
<AttributeDecoder xsi:type="ScopedAttributeDecoder"/>
|
||||
</Attribute>
|
||||
<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" id="eppn">
|
||||
<AttributeDecoder xsi:type="ScopedAttributeDecoder"/>
|
||||
</Attribute>
|
||||
|
||||
<Attribute name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" id="affiliation">
|
||||
<AttributeDecoder xsi:type="ScopedAttributeDecoder" caseSensitive="false"/>
|
||||
</Attribute>
|
||||
<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" id="affiliation">
|
||||
<AttributeDecoder xsi:type="ScopedAttributeDecoder" caseSensitive="false"/>
|
||||
</Attribute>
|
||||
|
||||
<Attribute name="urn:mace:dir:attribute-def:eduPersonAffiliation" id="unscoped-affiliation">
|
||||
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
|
||||
</Attribute>
|
||||
<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" id="unscoped-affiliation">
|
||||
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
|
||||
</Attribute>
|
||||
|
||||
<Attribute name="urn:mace:dir:attribute-def:eduPersonEntitlement" id="entitlement"/>
|
||||
<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" id="entitlement"/>
|
||||
|
||||
<!-- A persistent id attribute that supports personalized anonymous access. -->
|
||||
|
||||
<Attribute name="urn:mace:dir:attribute-def:eduPersonTargetedID" id="targeted-id">
|
||||
<AttributeDecoder xsi:type="ScopedAttributeDecoder"/>
|
||||
</Attribute>
|
||||
|
||||
<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" id="persistent-id">
|
||||
<AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
|
||||
</Attribute>
|
||||
|
||||
<Attribute name="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" id="persistent-id">
|
||||
<AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$NameQualifier!$SPNameQualifier!$Name" defaultQualifiers="true"/>
|
||||
</Attribute>
|
||||
|
||||
<!--
|
||||
The following attributes have been configured through Ansible.
|
||||
-->
|
||||
{% for idp in keystone_sp.trusted_idp_list %}
|
||||
{% if idp.protocols is defined %}
|
||||
{% for protocol in idp.protocols %}
|
||||
{% if protocol.name == "saml2" and protocol.attributes is defined %}
|
||||
{% for attr in protocol.attributes %}
|
||||
<Attribute{% for k in attr %} {{ k }}="{{ attr[k] }}"{% endfor %}/>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
</Attributes>
|
104
templates/shibboleth2.xml.j2
Normal file
104
templates/shibboleth2.xml.j2
Normal file
@ -0,0 +1,104 @@
|
||||
<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config"
|
||||
xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config"
|
||||
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
||||
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
|
||||
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
|
||||
clockSkew="180">
|
||||
|
||||
<!-- The entityID is the name by which your IdP will know your SP. -->
|
||||
<ApplicationDefaults entityID="{{ keystone_service_publicuri }}/shibboleth">
|
||||
|
||||
<!-- You should use secure cookies if at all possible. See cookieProps in this Wiki article. -->
|
||||
<!-- https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPSessions -->
|
||||
<Sessions lifetime="28800"
|
||||
timeout="3600"
|
||||
relayState="ss:mem"
|
||||
checkAddress="false"
|
||||
handlerSSL="{% if keystone_ssl_enabled | bool %}true{% else %}false{% endif %}"
|
||||
{% if keystone_service_publicuri_proto == "https" %}cookieProps="; path=/; secure"{% endif %}>
|
||||
|
||||
<!-- Triggers a login request directly to the IdP. -->
|
||||
<!-- https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPServiceSSO -->
|
||||
<SSO ECP="true" entityID="{{ keystone_sp.trusted_idp_list.0.entity_ids.0 }}">
|
||||
SAML2 SAML1
|
||||
</SSO>
|
||||
|
||||
<!-- SAML and local-only logout. -->
|
||||
<!-- https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPServiceLogout -->
|
||||
<Logout>SAML2 Local</Logout>
|
||||
|
||||
<!--
|
||||
Handlers allow you to interact with the SP and gather more information.
|
||||
Attribute values received by the SP through SAML will be visible at:
|
||||
{{ keystone_service_publicuri }}/Shibboleth.sso/Session
|
||||
-->
|
||||
|
||||
<!-- Extension service that generates "approximate" metadata based on SP configuration. -->
|
||||
<Handler type="MetadataGenerator"
|
||||
Location="/Metadata"
|
||||
signing="false"/>
|
||||
|
||||
<!-- Status reporting service. -->
|
||||
<Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>
|
||||
|
||||
<!-- Session diagnostic service. -->
|
||||
<Handler type="Session" Location="/Session" showAttributeValues="true"/>
|
||||
|
||||
<!-- JSON feed of discovery information. -->
|
||||
<Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
|
||||
</Sessions>
|
||||
|
||||
<!--
|
||||
Allows overriding of error template information/filenames. You can
|
||||
also add attributes with values that can be plugged into the templates.
|
||||
-->
|
||||
<Errors supportContact="root@localhost"
|
||||
helpLocation="/about.html"
|
||||
styleSheet="/shibboleth-sp/main.css"/>
|
||||
|
||||
<!--
|
||||
Loads and trusts a list of metadata files which describes
|
||||
the trusted IdP's and how to communicate with them.
|
||||
-->
|
||||
{% if keystone_sp.trusted_idp_list is defined -%}
|
||||
{% for item in keystone_sp.trusted_idp_list %}
|
||||
<MetadataProvider type="XML"
|
||||
uri="{{ item.metadata_uri }}"
|
||||
backingFilePath="{{ item.metadata_file }}"
|
||||
reloadInterval="{{ item.metadata_reload }}" />
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Map to extract attributes from SAML assertions. -->
|
||||
<AttributeExtractor type="XML"
|
||||
validate="true"
|
||||
reloadChanges="false"
|
||||
path="attribute-map.xml"/>
|
||||
|
||||
<!-- Use a SAML query if no attributes are supplied during SSO. -->
|
||||
<AttributeResolver type="Query" subjectMatch="true"/>
|
||||
|
||||
<!-- Default filtering policy for recognized attributes, lets other data pass. -->
|
||||
<AttributeFilter type="XML"
|
||||
validate="true"
|
||||
path="attribute-policy.xml"/>
|
||||
|
||||
<!-- Your SP generated these credentials. They're used to talk to IdP's. -->
|
||||
<CredentialResolver type="File"
|
||||
key="sp-key.pem"
|
||||
certificate="sp-cert.pem"/>
|
||||
|
||||
</ApplicationDefaults>
|
||||
|
||||
<!-- Policies that determine how to process and authenticate runtime messages. -->
|
||||
<SecurityPolicyProvider type="XML"
|
||||
validate="true"
|
||||
path="security-policy.xml"/>
|
||||
|
||||
<!-- Low-level configuration about protocols and bindings available for use. -->
|
||||
<ProtocolProvider type="XML"
|
||||
validate="true"
|
||||
reloadChanges="false"
|
||||
path="protocols.xml"/>
|
||||
|
||||
</SPConfig>
|
Loading…
Reference in New Issue
Block a user