Ipsilon attribute mapping and filtering

A SAML assertion can contain one or more attributes. These are basically pieces of information about the authenticated user. It is important to remember that they are only provided when the user logs in. So, for example, if a user logs in, then you change their e-mail address, the SAML assertion will reflect the original value until that user logs out and back in again.

Ipsilon provides two ways to control what attributes are sent in an assertion and what those attributes are named. This is called attribute mapping and allowed attributes.

Ipsilon supports two levels of mapping and attribute visibility:

  • global level configuration
  • per-SP configuration

These are not additive. If an SP provides its own mapping or list of allowed attributes then that overrides the global setting. It is, though, possible to mix one or the other. So you can have a global mapping and a SP-specific set of allowed attributes.

Info Plugins

It all begins with Info plugins. These retrieve the attributes from the identity source and the available attributes depend entirely on the capabilities of the info plugin. The nss plugin, for example, is limited to those things in <tt>/etc/passwd</tt>. The ldap plugin on the other hand can retrieve any attribute from LDAP.

The list of attributes available from the  SSSD info plugin is configured differently than other info plugins because root is required to manage the SSSD configuration file (<tt>/etc/sssd/sssd.conf</tt>).

The list of attributes is controlled by two variables: ldap_user_extra_attrs and user_attributes. ldap_user_extra_attrs tells sssd what extra attributes to request when it gets a user over LDAP (like in the IPA case). user_attributes controls what extra attributes are available over the SSSD info pipe (D-bus). See sssd-ldap(5) and sssd-ifp(5) for more details.

By default SSSD is configured to retrieve: mail, street, locality, postalCode, telephoneNumber, givenname and surname (sn).

Mapping and Filtering

Mapping allows you to rename an info variable to match the needs of your environment. For example, the user’s e-mail address is defined as mail by Ipsilon but your application may require it to be email. This can be managed via mapping.

Note that mapping an attribute does not remove the original. So if you were to create a mapping from mail -> email you would end up with the following attributes on the SP:

  • MELLON_MAIL=tuser@example.com
  • MELLON_EMAIL=tuser@example.com
  • MELLON_MAIL_0=tuser@example.com
  • MELLON_EMAIL_0=tuser@example.com

To remove the mail version you would need to use the Allowed Attributes setting to select only those attributes you want sent in the assertion.

The current filtering is a bit limited, providing only a white list of attributes. You can specify all attributes (*) or provide a discrete list of the attributes you want. You cannot specify negative attributes (e.g. all but mail) or a regular expression.

Ipsilon and IPA

Ipsilon is an IdP that supports SAML 2.0. Here I’ll show how the IPA integration works to use IPA as the source of SSL certificates and how to use IPA as the identity backend to Ipsilon.

I have an existing IPA installation that I’ll use as the IPA master. For Ipsilon I’ve got two Openstack VM (1GB RAM, 10GB disk) running Fedora 22.

Install the IdP

Pick one and this is the IdP.  Install the Ipsilon server packages:

$ sudo dnf install ipsilon ipsilon-infosssd ipsilon-saml2 ipsilon-authgssapi ipsilon-tools-ipa freeipa-client --enablerepo=updates-testing

Enroll the machine as an IPA client:

$ sudo ipa-client-install

Install the Ipsilon IdP:

$ sudo kinit admin
$ sudo ipsilon-server-install --ipa=yes --info-sssd=yes --form=yes

Have IPA issue an SSL certificate for Apache:

$ sudo systemctl start certmonger
$ sudo ipa-getcert request -f /etc/pki/tls/certs/server.pem -k /etc/pki/tls/private/server.key -K HTTP/`hostname`

Configure Apache to use this certificate.

$ sudo  /etc/httpd/conf.d/ssl.conf

Modify SSLCertificateFile and SSLCertificateKeyFile to:

SSLCertificateFile /etc/pki/tls/certs/server.pem
SSLCertificateKeyFile /etc/pki/tls/private/server.key

Restart Apache:

$ sudo systemctl restart httpd

Note: As of today there is an SELinux issue preventing Apache from reading ipsilon.conf. I set it to permissive mode.

Test to see that SSL trust is working and the IdP is serving pages:

$ curl https://`hostname`/idp

Scan the output and you should see a link to /idp/login. If you do then it’s working.

Ok, let’s check it out for real now. Fire up a browser and head to https://idp/

You should see a form login. Login using the IPA admin and password. Woo, integration! If you want to really test it, log out, kinit as admin on the machine you launched the browser from (assuming it is an IPA client) and try again and you should get right in.

Install the Service Provider

Let’s a pause a moment and switch over to your other VM onto which we’ll install the Service Provider (SP). The process is similar.

Install the ipsilon and IPA client packages:

$ sudo dnf install ipsilon-client freeipa-client freeipa-admintools mod_ssl --enablerepo=updates-testing

Enroll as an IPA client:

$ sudo ipa-client-install

Install the Ipsilon SP:

$ sudo ipsilon-client-install --saml-idp-metadata https://ipsilon.example.com/idp/saml2/metadata --saml-auth /secure

Create an SSL certificate for the SP webserver:

$ sudo kinit admin
$ sudo ipa service-add HTTP/`hostname` --force
$ sudo ipa-getcert request -f /etc/pki/tls/certs/server.pem -k /etc/pki/tls/private/server.key -K HTTP/`hostname`

Configure Apache to use this certificate.

$ sudo  /etc/httpd/conf.d/ssl.conf

Modify SSLCertificateFile and SSLCertificateKeyFile to:

SSLCertificateFile /etc/pki/tls/certs/server.pem
SSLCertificateKeyFile /etc/pki/tls/private/server.key

Restart Apache:

$ sudo systemctl restart httpd

Register the SP

Now we need to register the SP with the IdP. To do this bring up your browser window we opened with the IdP and head to Administration -> Identity Providers -> saml2 -> Manage -> Add New

The name is not important, it is just a unique identifier for the IdP to reference the SP. I tend to use the hostname of the SP.

The metadata can be found on the SP in the filesystem in /etc/httpd/saml2/<fqdn>

For the metadata you can either:

  1. Download the metadata to the machine running the browser, select Browse, find the file and upload it.
  2. Provide the metadata via a URL (https://sp.example.com/saml2/metadata)
  3. Copy and paste the metadata

The resulting page is the configuration page for the SP. We can leave the defaults for now.

Configure the SP secure pages

Let’s create some secure content to serve on the SP.

$ sudo vi /var/www/html/secure/index.html

Add some content like:

<html><title>Secure</title>Hello there</html>

Now confirm that it requires authentication:

$ curl https://`hostname`/secure/

You should get back a 303 See Other response.

Now try this in your browser. You should be redirected to the IdP to authentication. Do so using the IPA admin credentials. After authenticating you should be redirected back to /secure on the SP and see the text “Hello there”. Success!

Test Logout

Modify the index.html we just created to include a link to

<a href="/saml2/logout?ReturnTo=https://sp.example.com/logged_out.html">Log out</a>

Create a logout landing point (note it is outside the secured area):

$ sudo vi /var/www/html/logged_out.html

with contents:

<html>
<title>Logout</title>
<p>
Congratulations, you've been logged out!
</p>
<p>
Now try to <a href="/secure/">log back in</a>
</p>
</html>

You can just refresh the secured page and you should have a Log out link.

Click that and you should see a logout message and a link to log back in. If you click that you will be asked to re-authenticate.

For further exercises, stand up another SP. You’ll find that once you authenticate to one SP you are allowed in with no authentication request on the other one. Similarly, logging out of one logs out of all.

Add more users

So far we’ve limited things to only the IPA admin user. Let’s add a regular IPA user and authenticate as them. On either the SP or the IdP run:

$ kinit admin
$ ipa user-add --first=Test --last=User tuser1 --password
Password: 
Enter Password again to verify:
$ kinit tuser1
Password for tuser1@EXAMPLE.COM: 
Password expired.  You must change it now.
Enter new password: 
Enter it again:

Now request /secure/ on the SP again and this time authenticate as tuser1. This will work for any IPA user.

Attribute Data

Ipsilon can configure what user information is visible to a given SP and can optionally rename some attributes (called mapping).

A broad way to see what is available is to use Server-Side Includes. Let’s play.

Enable SSI in Apache by editing /etc/httpd/conf.d/ipsilon-saml.conf and adding Options +Includes to the secure Location and a new output filter. It should look like:

    MellonEnable "auth"
    Header append Cache-Control "no-cache"
    Options +Includes

AddOutputFilter INCLUDES .html

Note that you wouldn’t want to do this in production, we’re just playing here.

Restart apache

$ sudo systemctl restart httpd

Configure your secure index.html to display the environment. Add this to the end of the file, before </html>:

<!--#printenv -->

The output is rather ugly, one very long line of output. We’re interested in those attributes prefixed with MELLON_. In my case it is:

MELLON_NAME_ID=tuser1 MELLON_NAME_ID_0=tuser1 MELLON_surname=User MELLON_surname_0=User MELLON_groups=ipausers MELLON_groups_0=ipausers MELLON_givenname=Test MELLON_givenname_0=Test MELLON_fullname=Test User MELLON_fullname_0=Test User MELLON_email=tuser1@greyoak.com MELLON_email_0=tuser1@greyoak.com MELLON_IDP=https://ipsilon.greyoak.com/idp/saml2/metadata MELLON_IDP_0=https://ipsilon.greyoak.com/idp/saml2/metadata 

When we installed Ipsilon we enabled the SSSD info plugin. This controls what information is retrieved by SSSD from IPA when a user authenticates. Ipsilon is configured to retrieve the LDAP attributes mail, street, locality, postalCode, telephoneNumber, givenname and surname. We don’t see any address information here because we didn’t configure it for the user, let’s do that now.

$ ipa user-mod --street="123 Main" --city=Baltimore --postalcode=21234 tuser1

Log out of the SP and log back in and you should now have MELLON_ variables for street, state and postalcode.

If you’re wondering why there are _0 versions of these as well it is a mechanism to support multi-valued attributes.