SAML Federation with Openstack

This is a bit of a followup to my last post on Kerberos-based federation so this post will make a lot more sense if you read that one. Kerberos didn’t really suit my needs because there’s no real web sign on to speak of, so getting hold of a Kerberos ticket in a friendly way on non-Windows platforms is problematic. The answer to this is to use SAML,which has some good support in Keystone, and more to come.

Prerequisites

I’m not going to go into too much detail of how SAML works here, and assume you know a little, or are prepared to infer things as you go from this post. There’s more detailed information in the Shibboleth wiki but importantly you must know the concept of an identity provider (which holds authentication data) and a service provider (which protects a resource).

In this example. I’m going to use Shibboleth as a service provider, and the testshib.org service as an identity provider.

As before, I am doing all this on Ubuntu so if you’re on a different OS you’ll have to tweak things.

Important!

Shibboleth is quite solid but its logs and error messages are extremely cryptic and not particularly helpful. There are quite a few gotchas, and it simply doesn’t tell you exactly what went wrong. The main one is that all the entityID configs for Shibboleth and in Keystone MUST match up, and Apache must have its ServerName configured to the matching domain name.

Apache config

You will need the shibboleth module for Apache so go ahead and install it:

sudo apt-get install libapache2-mod-shib2

That will enable the module, so you don’t need to explicity do that. You’ll also have a shibd daemon running after installation.

Inside your Virtualhost block in /etc/apache2/sites-enabled/keystone, you’ll need to add some Shibboleth config:

<Virtualhost *:5000>
...

  WSGIScriptAliasMatch ^(/v3/OS-FEDERATION/identity_providers/.*?/protocols/.*?/auth)$ /var/www/keystone/main/$1
  <Location ~ "/v3/auth/OS-FEDERATION/websso/saml2">
    ShibRequestSetting requireSession 1
    AuthType shibboleth
    # ShibRequireAll On  # Enable this if you're using 12.043
    ShibRequireSession On
    ShibExportAssertion Off
    Require valid-user
  </Location>
</Virtualhost>

<VirtualHost *:80>
  <Location /Shibboleth.sso>
    SetHandler shib
  </Location>
</VirtualHost>

You also need to make sure that your Apache knows what its server name is. If it complains that it doesn’t when you restart it, add an explicit ServerName directive that matches the exact domain name that you are going to give to testshib, shortly.

Now restart Apache.

sudo service apache2 restart

Testshib config

Visit http://testshib.org/ and follow the instructions carefully. It will eventually generate some Shibboleth configuration for your service provider, which you need to save as /etc/shibboleth/shibboleth2.xml

If you take a look in the config, you’ll see three main important things.

<ApplicationDefaults entityID="<your service provider ID>" REMOTE_USER="eppn">

You need to remove REMOTE_USER entirely as this causes Keystone to do the wrong thing.

Inside the ApplicationDefaults you’ll see:

<SSO entityID="https://idp.testshib.org/idp/shibboleth">
    SAML2 SAML1
</SSO>

This is the part that tells Shibboleth what the ID of the identity provider is. Further down the file you’ll see something like:

<MetadataProvider type="XML" uri="http://www.testshib.org/metadata/testshib-providers.xml"
 backingFilePath="testshib-two-idp-metadata.xml" reloadInterval="180000" />

It tells Shibboleth where to get the IdP’s metadata, which describes how to interact with it (mainly URLs and signing keys).

These three parts are the main parts of the config that describe the remote IdP. If you change the IdP for a different one, it’s unlikely you’ll need to edit anything else.

Keystone config

As in the Kerberos post, you need to enable some things in the keystone.conf. Since I wrote that post, I’ve seen that federation is enabled by default in Kilo, so there’s much less to do now. Basically:

[auth]
saml2 = keystone.auth.plugins.mapped.Mapped

[saml2]
remote_id_attribute = Shib-Identity-Provider
  • Copy the callback template to the right place:
cp /opt/stack/keystone/etc/sso_callback_template.html /etc/keystone/
  • Create the federation database tables if you haven’t already:
keystone-manage db_sync --extension federation

Keystone mapping data configuration

As before, we have to use the v3 API for federation. If you have sourced the credentials file already, you can just do two more environment variables:

export OS_AUTH_URL=http://$HOSTNAME:5000/v3
export OS_IDENTITY_API_VERSION=3

You may remember from the Kerberos post that we need a mapping file. The mapping used for kerberos can be re-used for this SAML authentication, here it is:

[
  {
    "local": [
      {
        "user": {
          "name": "{0}",
          "domain": {"name": "Default"}
        }
      },
      {
        "group": {
          "id": "GROUP_ID"
        }
      }
    ],
    "remote": [
      {
        "type": "REMOTE_USER"
      }
    ]
  }
]

Save this as a file called add-mapping.json.  Although it can be re-used from before, I’ll re-add it here for completeness:

openstack group create samlusers
openstack role add --project demo --group samlusers member
openstack identity provider create testshib
group_id=`openstack group list|grep samlusers|awk '{print $2}'`
cat add-mapping.json|sed s^GROUP_ID^$group_id^ > /tmp/mapping.json
openstack mapping create --rules /tmp/mapping.json saml_mapping
openstack federation protocol create --identity-provider testshib --mapping saml_mapping saml2
openstack identity provider set --remote-id <your entity ID> testshib

Replace <your entity ID> with the value mentioned above in the SSO entityId in the shibboleth2.xml config. Shibboleth sets Shib-Identiy-Id in the Apache request variables with the value of the entityId used, and we configured keystone to use this in keystone.conf above. This is the “remote id” for the identity provider, and keystone uses this to apply the correct protocol and mapping.

Horizon config

As before, a few Django config tweaks are needed. Edit the /opt/stack/horizon/openstack_dashboard/local/local_settings.py

WEBSSO_ENABLED = True
WEBSSO_CHOICES = (
 ("credentials", _("Keystone Credentials")),
 ("testshib", _("Testshib SAML")),
 )
WEBSSO_INITIAL_CHOICE="testshib"
OPENSTACK_API_VERSIONS = {
 "identity": 3
}
OPENSTACK_KEYSTONE_URL="http://$HOSTNAME:5000/v3"

Replace $HOSTNAME with your actual keystone hostname.

Now, restart apache2 and shibd:

service apache2 restart
service shibd restart

You should now be all set. After making sure “Testshib SAML” is selected in the login screen, click connect and you will be redirected to the testshib login page. It has its own fixed users and tells you what they are when you visit that page.

Good luck!

Advertisements

About bigjools

Python hacker and chronic Lyme Disease sufferer.
This entry was posted in Uncategorized. Bookmark the permalink.

2 Responses to SAML Federation with Openstack

  1. Bogdan says:

    Just wondering how could this setup work if you completely remove REMOTE_USER from shibboleth2.xml and at the same time use in mappings remote “type”: “REMOTE_USER”. You should either define how REMOTE_USER to be populate so that mapping can use it or you should change the mapping to not use REMOTE_USER but something else instead (e.g. eppn).

  2. Arun Dendukuri says:

    will you able to offer your training to mentor me in keystone federation.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s