22 KiB
Configuring Keystone for Federation
Keystone as a Service Provider (SP)
Prerequisites
If you are not familiar with the idea of federated identity, see the introduction first.
In this section, we will configure keystone as a Service Provider, consuming identity properties issued by an external Identity Provider, such as SAML assertions or OpenID Connect claims. For testing purposes, we recommend using samltest.id as a SAML Identity Provider, or Google as an OpenID Connect Identity Provider, and the examples here will references those providers. If you plan to set up Keystone as an Identity Provider (IdP), it is easiest to set up keystone with a dummy SAML provider first and then reconfigure it to point to the keystone Identity Provider later.
The following configuration steps were performed on a machine running Ubuntu 16.04 and Apache 2.4.18.
To enable federation, you'll need to run keystone behind a web server such as Apache rather than running the WSGI application directly with uWSGI or Gunicorn. See the installation guide for SUSE, RedHat or Ubuntu to configure the Apache web server for keystone.
Throughout the rest of the guide, you will need to decide on three pieces of information and use them consistently throughout your configuration:
- The protocol name. This must be a valid keystone auth method and
must match one of:
saml2
,openid
,mapped
or a custom auth method for which you must register as an external driver. - The identity provider name. This can be arbitrary.
- The entity ID of the service provider. This should be a URN but need not resolve to anything.
You will also need to decide what HTTPD module to use as a Service
Provider. This guide provides examples for mod_shib
and
mod_auth_mellon
as SAML service providers, and
mod_auth_openidc
as an OpenID Connect Service Provider.
Note
In this guide, the keystone Service Provider is configured on a host
called sp.keystone.example.org listening on the standard HTTPS port. All
keystone paths will start with the keystone version prefix,
/v3
. If you have configured keystone to listen on port
5000, or to respond on the path /identity
(for example),
take this into account in your own configuration.
Creating federation resources in keystone
You need to create three resources via the keystone API to identify the Identity Provider to keystone and align remote user attributes with keystone objects:
See also the keystone federation API reference.
Create an Identity Provider
Create an Identity Provider object in keystone, which represents the Identity Provider we will use to authenticate end users:
$ openstack identity provider create --remote-id https://samltest.id/saml/idp samltest
The value for the remote-id
option is the unique
identifier provided by the Identity Provider, called the entity ID or the remote
ID. For a SAML Identity Provider, it can found by querying its
metadata endpoint:
$ curl -s https://samltest.id/saml/idp | grep -o 'entityID=".*"'
entityID="https://samltest.id/saml/idp"
For an OpenID Connect IdP, it is the Identity Provider's Issuer Identifier. A remote ID must be globally unique: two identity providers cannot be associated with the same remote ID. The remote ID will usually appear as a URN but but need not be a resolvable URL.
The local name, called samltest
in our example, is
decided by you and will be used by the mapping and protocol, and later
for authentication.
Note
An identity provider keystone object may have multiple
remote-ids
specified, this allows the same
keystone identity provider resource to be used with multiple
external identity providers. For example, an identity provider resource
university-idp
, may have the following
remote_ids
:
['university-x', 'university-y', 'university-z']
. This
removes the need to configure N identity providers in keystone.
See also the API reference on identity providers.
Create a Mapping
Next, create a mapping. A mapping is a set of rules that link the attributes of a remote user to user properties that keystone understands. It is especially useful for granting remote users authorization to keystone resources, either by associating them with a local keystone group and inheriting its role assignments, or dynamically provisioning projects within keystone based on these rules.
An Identity Provider has exactly one mapping specified per protocol. Mapping objects can be used multiple times by different combinations of Identity Provider and Protocol.
As a simple example, create a mapping with a single rule to map all remote users to a local user in a single group in keystone:
$ cat > rules.json <<EOF
[
{
"local": [
{
"user": {
"name": "{0}"
},
"group": {
"domain": {
"name": "Default"
},
"name": "federated_users"
}
}
],
"remote": [
{
"type": "REMOTE_USER"
}
]
}
]
EOF
$ openstack mapping create --rules rules.json samltest_mapping
This mapping rule evaluates the REMOTE_USER
variable set
by the HTTPD auth module and uses it to fill in the name of the local
user in keystone. It also ensures all remote users become effective
members of the federated_users
group, thereby inheriting
the group's role assignments.
In this example, the federated_users
group must exist in
the keystone Identity backend and must have a role assignment on some
project, domain, or system in order for federated users to have an
authorization in keystone. For example, to create the group:
$ openstack group create federated_users
Create a project these users should be assigned to:
$ openstack project create federated_project
Assign the group a member
role in the project:
$ openstack role add --group federated_users --project federated_project member
Mappings can be quite complex. A detailed guide can be found on the
mapping_combinations
page.
See also the API reference on mapping rules.
Create a Protocol
Now create a federation protocol. A federation protocol object links the Identity Provider to a mapping.
You can create a protocol like this:
$ openstack federation protocol create saml2 \
--mapping samltest_mapping --identity-provider samltest
As mentioned in sp-prerequisites
, the name you give the protocol is
not arbitrary, it must be a valid auth method.
See also the API reference for federation protocols.
Configuring an HTTPD auth module
This guide currently only includes examples for the Apache web server, but it possible to use SAML, OpenIDC, and other auth modules in other web servers. See the installation guides for running keystone behind Apache for SUSE, RedHat or Ubuntu.
Configure protected endpoints
There is a minimum of one endpoint that must be protected in the VirtualHost configuration for the keystone service:
<Location /v3/OS-FEDERATION/identity_providers/IDENTITYPROVIDER/protocols/PROTOCOL/auth>
valid-user
RequireAuthType [...]
...</Location>
This is the endpoint for federated users to request an unscoped token.
If configuring WebSSO, you should also protect one or both of the following endpoints:
<Location /v3/auth/OS-FEDERATION/websso/PROTOCOL>
valid-user
RequireAuthType [...]
...</Location>
<Location /v3/auth/OS-FEDERATION/identity_providers/IDENTITYPROVIDER/protocols/PROTOCOL/websso>
valid-user
RequireAuthType [...]
...</Location>
The first example only specifies a protocol, and keystone will use the incoming remote ID to determine the Identity Provider. The second specifies the Identity Provider directly, which must then be supplied to horizon when configuring horizon for WebSSO.
The path must exactly match the path that will be used to access the
keystone service. For example, if the identity provider you created in
Create an Identity Provider
is samltest
and the protocol you created in Create a Protocol is saml2
,
then the Locations will be:
<Location /v3/OS-FEDERATION/identity_providers/samltest/protocols/saml2/auth>
valid-user
RequireAuthType [...]
...</Location>
<Location /v3/auth/OS-FEDERATION/websso/saml2>
valid-user
RequireAuthType [...]
...</Location>
<Location /v3/auth/OS-FEDERATION/identity_providers/samltest/protocols/saml2/websso>
valid-user
RequireAuthType [...]
...</Location>
However, if you have configured the keystone service to use a virtual
path such as /identity
, that part of the path should be
included:
<Location /identity/v3/OS-FEDERATION/identity_providers/samltest/protocols/saml2/auth>
valid-user
RequireAuthType [...]
...</Location>
...
Configure the auth module
If your Identity Provider is a SAML IdP, there are two main Apache modules that can be used as a SAML Service Provider: mod_shib and mod_auth_mellon. For an OpenID Connect Identity Provider, mod_auth_openidc is used. You can also use other auth modules such as kerberos, X.509, or others. Check the documentation for the provider you choose for detailed installation and configuration guidance.
Depending on the Service Provider module you've chosen, you will need to install the applicable Apache module package and follow additional configuration steps. This guide contains examples for two major federation protocols:
- SAML2.0 - see guides for the following implementations:
- OpenID Connect: Set up mod_auth_openidc.
Configuring Keystone
While the Apache module does the majority of the heavy lifting, minor changes are needed to allow keystone to allow and understand federated authentication.
Add the Auth Method
Add the authentication methods to the [auth]
section in
keystone.conf
. The auth method here must have the same name
as the protocol you created in Create a
Protocol. You should also remove external
as an
allowable method.
[auth]
methods = password,token,saml2,openid
When finished configuring keystone, restart the keystone WSGI process or the web server:
# systemctl restart apache2
Authenticating
Use the CLI to authenticate with a SAML2.0 Identity Provider
The python-openstackclient
can be used to authenticate a
federated user in a SAML Identity Provider to keystone.
Note
The SAML Identity Provider must be configured to support the ECP authentication profile.
To use the CLI tool, you must have the name of the Identity Provider resource in keystone, the name of the federation protocol configured in keystone, and the ECP endpoint for the Identity Provider. If you are the cloud administrator, the name of the Identity Provider and protocol was configured in Create an Identity Provider and Create a Protocol respectively. If you are not the administrator, you must obtain this information from the administrator.
The ECP endpoint for the Identity Provider can be obtained from its
metadata without involving an administrator. This endpoint is the
urn:oasis:names:tc:SAML:2.0:bindings:SOAP
binding in the
metadata document:
$ curl -s https://samltest.id/saml/idp | grep urn:oasis:names:tc:SAML:2.0:bindings:SOAP
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://samltest.id/idp/profile/SAML2/SOAP/ECP"/>
Find available scopes
If you are a new user and are not aware of what resources you have access to, you can use an unscoped query to list the projects or domains you have been granted a role assignment on:
export OS_AUTH_TYPE=v3samlpassword
export OS_IDENTITY_PROVIDER=samltest
export OS_IDENTITY_PROVIDER_URL=https://samltest.id/idp/profile/SAML2/SOAP/ECP
export OS_PROTOCOL=saml2
export OS_USERNAME=morty
export OS_PASSWORD=panic
export OS_AUTH_URL=https://sp.keystone.example.org/v3
export OS_IDENTITY_API_VERSION=3
openstack federation project list
openstack federation domain list
Get a scoped token
If you already know the project, domain or system you wish to scope to, you can directly request a scoped token:
export OS_AUTH_TYPE=v3samlpassword
export OS_IDENTITY_PROVIDER=samltest
export OS_IDENTITY_PROVIDER_URL=https://samltest.id/idp/profile/SAML2/SOAP/ECP
export OS_PROTOCOL=saml2
export OS_USERNAME=morty
export OS_PASSWORD=panic
export OS_AUTH_URL=https://sp.keystone.example.org/v3
export OS_IDENTITY_API_VERSION=3
export OS_PROJECT_NAME=federated_project
export OS_PROJECT_DOMAIN_NAME=Default
openstack token issue
Use horizon to authenticate with an external Identity Provider
When horizon is configured to enable WebSSO, a dropdown menu will appear on the login screen before the user has authenticated. Select an authentication method from the menu to be redirected to your Identity Provider for authentication.
Keystone as an Identity Provider (IdP)
Prerequisites
When keystone is configured as an Identity Provider, it is often referred to as Keystone to Keystone, because it enables federation between multiple OpenStack clouds using the SAML2.0 protocol.
If you are not familiar with the idea of federated identity, see the introduction first.
When setting up Keystone to Keystone, it is easiest to configure a keystone Service Provider first with a sandbox Identity Provider such as samltest.id.
This feature requires installation of the xmlsec1 tool via your distribution packaging system (for instance apt or yum)
# apt-get install xmlsec1
Note
In this guide, the keystone Identity Provider is configured on a host
called idp.keystone.example.org listening on the standard HTTPS port.
All keystone paths will start with the keystone version prefix,
/v3
. If you have configured keystone to listen on port
5000, or to respond on the path /identity
(for example),
take this into account in your own configuration.
Configuring Metadata
Since keystone is acting as a SAML Identity Provider, its metadata
must be configured in the [saml]
section of
keystone.conf
so that it can served by the metadata
API.
The two parameters that must be set in order for
keystone to generate metadata are idp_entity_id
and
idp_sso_endpoint
:
[saml]
idp_entity_id=https://idp.keystone.example.org/v3/OS-FEDERATION/saml2/idp
idp_sso_endpoint=https://idp.keystone.example.org/v3/OS-FEDERATION/saml2/sso
idp_entity_id
sets the Identity Provider entity ID,
which is a string of your choosing that uniquely identifies the Identity
Provider to any Service Provider.
idp_sso_endpoint
is required to generate valid metadata,
but its value is currently not used because keystone as an Identity
Provider does not support the SAML2.0 WebSSO auth profile. This may
change in the future which is why there is no default value provided and
must be set by the operator.
For completeness, the following Organization and Contact configuration options should also be updated to reflect your organization and administrator contact details.
idp_organization_name=example_company
idp_organization_display_name=Example Corp.
idp_organization_url=example.com
idp_contact_company=example_company
idp_contact_name=John
idp_contact_surname=Smith
idp_contact_email=jsmith@example.com
idp_contact_telephone=555-555-5555
idp_contact_type=technical
It is important to take note of the default certfile
and
keyfile
options, and adjust them if necessary:
certfile=/etc/keystone/ssl/certs/signing_cert.pem
keyfile=/etc/keystone/ssl/private/signing_key.pem
You must generate a PKI key pair and copy the files to these paths.
You can use the openssl
tool to do so. Keystone does not
provide a utility for this.
Check the idp_metadata_path
setting and adjust it if
necessary:
idp_metadata_path=/etc/keystone/saml2_idp_metadata.xml
To create metadata for your keystone IdP, run the
keystone-manage
command and redirect the output to a file.
For example:
# keystone-manage saml_idp_metadata > /etc/keystone/saml2_idp_metadata.xml
Finally, restart the keystone WSGI service or the web server frontend:
# systemctl restart apache2
Creating a Service Provider Resource
Create a Service Provider resource to represent your Service Provider as an object in keystone:
$ openstack service provider create keystonesp \
--service-provider-url https://sp.keystone.example.org/Shibboleth.sso/SAML2/ECP
--auth-url https://sp.keystone.example.org/v3/OS-FEDERATION/identity_providers/keystoneidp/protocols/saml2/auth
The --auth-url
is the federated
auth endpoint for a specific Identity Provider and protocol name,
here named keystoneidp
and saml2
.
The --service-provider-url
is the
urn:oasis:names:tc:SAML:2.0:bindings:PAOS
binding for the
Assertion Consumer Service of the Service Provider. It can be obtained
from the Service Provider metadata:
$ curl -s https://sp.keystone.example.org/Shibboleth.sso/Metadata | grep urn:oasis:names:tc:SAML:2.0:bindings:PAOS
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://sp.keystone.example.org/Shibboleth.sso/SAML2/ECP" index="4"/>
Authenticating
Use the CLI to authenticate with Keystone-to-Keystone
Use python-openstackclient
to authenticate with the IdP
and then get a scoped token from the SP.
export OS_USERNAME=demo
export OS_PASSWORD=nomoresecret
export OS_AUTH_URL=https://idp.keystone.example.org/v3
export OS_IDENTITY_API_VERSION=3
export OS_PROJECT_NAME=federated_project
export OS_PROJECT_DOMAIN_NAME=Default
export OS_SERVICE_PROVIDER=keystonesp
export OS_REMOTE_PROJECT_NAME=federated_project
export OS_REMOTE_PROJECT_DOMAIN_NAME=Default
openstack token issue
Use Horizon to switch clouds
No additional configuration is necessary to enable horizon for Keystone to Keystone. Log into the horizon instance for the Identity Provider using your regular local keystone credentials. Once logged in, you will see a Service Provider dropdown menu which you can use to switch your dashboard view to another cloud.