Vladimir's general Shiboleth notes

From BeSTGRID

Jump to: navigation, search

This is a place-holder page where I want to keep my notes at least vaguely related to Shibboleth. I hope this may be useful of others as well. But it's generally intended as a place for notes I consider useful for myself...


Contents

[edit] Signing XML documents

The MAMS testbed federation puts signatures into the federation metadata XML documents. The signatures, inserted at the beginning of the document, have a digest of the canonic form the the remaining on documents, a signature of the digest, and the certificate for the key used to create the signature.

I was looking at what are the steps to create such signatures. The Apache XML Security project, http://xml.apache.org/security/, provides a Java and C library which allow to handle, and also create signed XML document. (The C library project is at http://xml.apache.org/security/c/)

I was looking for command-line tools which could be used to sign XML documents in a scripting environment. The C library (which is compiled as a part of installing the Shibboleth SP) has the templatesign tool. The tool needs a template for the signature to already exist as the first child of the top-level document. Then, the tool can be simple used as in the following example:

./templatesign --rsakey /etc/certs/mykey.pem "" --x509cert /etc/certs/mycert.pem /tmp/bestgrid-metadata.xml > /tmp/bestgrid-metadata-signed.xml

The template to be included is:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"></ds:CanonicalizationMethod>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
    <ds:Reference URI="">
      <ds:Transforms>
        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"></ds:Transform>
      </ds:Transforms>
      <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
      <ds:DigestValue>  </ds:DigestValue>
    </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>

  </ds:SignatureValue>
</ds:Signature>

[edit] Shibboleth Logo on SP Error Pages

In the default installation of a SP, the error page does not display properly - it links to the Shibboleth stylesheet and logo at an non-existent location, /shibtarget/logo.jpg and /shibtarget/main.css.

The locations are configured in shibboleth.xml - however, in order for them to be accessible, the same names must be aliased to local files in the httpd configuration.

Following the configuration on the BeSTGRID wiki, I will configure both at "/shibboleth-sp" in shib-sp.conf on RedHat and mod_shib.conf on Debian/Ubuntu.

The following httpd configuration fragment makes the logo and stylesheet accessible. Note that the path to the resources may vary with the system is - the following works on systems where the Shibboleth SP is installed into /usr/local/shibboleth-sp, according to the MAMS instructions.

<IfModule mod_alias.c>
  <Location /shibboleth-sp>
    Allow from all
  </Location>
  Alias /shibboleth-sp/main.css /usr/local/shibboleth-sp/doc/shibboleth/main.css
  Alias /shibboleth-sp/logo.jpg /usr/local/shibboleth-sp/doc/shibboleth/logo.jpg
</IfModule>

Also, shibboleth.xml has to be adjusted to use the new locations in error messages (and it also pays off to enter a real email address into the configuration):

               <Errors session="/usr/local/shibboleth-sp/etc/shibboleth/sessionError.html"
                       metadata="/usr/local/shibboleth-sp/etc/shibboleth/metadataError.html"
                       rm="/usr/local/shibboleth-sp/etc/shibboleth/rmError.html"
                       access="/usr/local/shibboleth-sp/etc/shibboleth/accessError.html"
                       supportContact="vladimir.mencl@canterbury.ac.nz"
                       logoLocation="/shibboleth-sp/logo.jpg"
                       styleSheet="/shibboleth-sp/main.css"/>


[edit] Controlling Scope for an IdP

An IdP may be assigning a Scope to some attributes (such as eduPersonPrincipalName or eduPersonAffiliation). The metadata determines which values an IdP may use for the scope. The <shib:Scope> extension gives the permissible value (or optionally a regular expression). For the AAF federations, the scope is determined from the entityId of the organization - it is exactly the hostname specified as the last part of the entityId (see example below).

For an organization, the hostname of the IdP might take the form idp.organization.ac.nz, while the preferred scope would be just organization.ac.nz. The solution is to register the IdP with an entityId containing just the preferred value of the scope range (and to register the services running on the IdP with its actual hostname).

For the University of Canterbury, the organization's (and IdP's) entity Id is:
urn:mace:federation.org.au:testfed:canterbury.ac.nz

This results into the <shib:Scope> extension having the value canterbury.ac.nz - while the hostname of the IdP still remains idp.canterbury.ac.nz.

[edit] Access control with Shibboleth: requesting a specific attribute

So far, the only form of access control used in the sample Shibboleth settings was requiring that a user authenticates with an IdP in the federation - and this plain membership was sufficient. It is possible to control access based on the presence of an attribute, or even a specific value of an attribute right at the level of Apache access control with the Shibboleth module.

The very simple form of doing that is:

    <Location /secure>
       AuthType shibboleth
       ShibRequireSession On
       # require valid-user
       require user ~ ^.+$
    </Location>

This specific example asks for the user variable to be set to any value - and any Shibboleth attribute can be used with the variable name it is assigned to in the Attribute Acceptance policy (AAP.xml).

Users who do not have the attribute (or do not provide it), get the following error message (with the Shibboleth logo):

Authorization Failed
Based on the information provided to this application about you, you are not authorized to access the resource at "https://idp-test.canterbury.ac.nz/secure/phpinfo.php"
Please contact the administrator of this service or application if you believe this to be an error.

This form of control however may not be that user friendly - user would have to know to go either use Autograph to allow the release of the attribute, or talk to their IdP administrator to configure the attributes on the IdP.

Also note that this does not work with lazy sessions - in which case one immediately gets the same error message.

Further, note that care must be taken with overlapping <Location> access control blocks. These should be listed from the most-generic ("/") to the most specific (as "/secure" in the above example). Otherwise, the more relaxed settings on the generic one would override the more stringent settings on the specific one.

[edit] Enforcing Canonical Hostnames

Issue: when a SP is accessed by a URL other than it's cannonical one, the local WAYF redirector (Session Initiator) constructs a URL containing the non-canonical hostname (followed by /Shibboleth.sso) - and consequently, IdP produces a Session Creation Failure with the reason:

org.opensaml.SAMLException: Invalid assertion consumer service URL.
  • Solution attempt 1: absolute shibboleth.xml handlerURL (does not work).

I thought I could fix it by editing <Sessions> element in shibboleth.xml, and change the attribute handlerURL from relative URL "/Shibboleth.sso" to an absolute URL containing the correct hostname.

Surprisingly, doing so results in a 50% failure rate in creating sessions, with the message

Session creation failure at (https://idp-test.canterbury.ac.nz/Shibboleth.sso/SAML/Artifact)
Session Creation Error

displayed in the HTML response, and SP log saying:

2008-02-26 13:52:13 ERROR shibd.Listener [23] sessionNew: caught exception while creating session: SOAPHTTPBindingProvider::send() failed while contacting SAML responder: error:1408F06B:SSL routines:SSL3_GET_RECORD:bad decompression

and no useful information in the IdP log.

Even more surprisingly, when I manually edit the URL when at the WAYF server, and switch from Artifact profile to POST profile, I don't get this failure, but I don't get any attributes at all. (In the previous case, if a session is established, I have all attributes there). Strange: authentication succeeds, but all attributes are rejected - even though in the POST profile, everything is sent in a single signed assertion.

Finally, more surprise, in each case, I'm so far redirected to the registered SP home page, but not to the page where I wanted to go.

I thought about the fact that I'm accessing the SP just by the short name "idp-test" and the server does not search "canterbury.ac.nz"? It however can resolve "idp-test" locally.


When I access the server by it's canonical name, these oddities do not kick in - so I'd better try redirect the URL already at Apache level.


Put the following inside <VirtualHost 132.181.4.4:80>:

RewriteEngine On
RewriteCond %{HTTP_HOST}   !^idp-test\.canterbury\.ac\.nz [NC]
RewriteCond %{HTTP_HOST}   !^$
RewriteRule ^/(.*)         http://idp-test.canterbury.ac.nz/$1 [L,R]

This works to redirect http requests to port 80 - how comes it works even for requests which are immediately redirected to the WAYF server (to go to IdP) by the Shibboleth module? The consumer service URL at the WAYF server already has the canonical hostname.

It however does not work for requests directed to the application-level WAYF redirector:

https://idp-test/Shibboleth.sso/WAYF/level-1.federation.org.au?target=http://idp-test/secure/

still asks for "idp-test/Shibboleth.sso" - which is still broken.

Surprisingly, expanding the hostname in the target URL parameter to the canonical hostname:

 https://idp-test/Shibboleth.sso/WAYF/level-1.federation.org.au?target=http://idp-test.canterbury.ac.nz/secure/

works and access the consumer service via the canonical hostname.

It appears that we cannot redirect all wrong ways of accessing the SP, but we can redirect all ways of entering the SP to the canonical hostname, and this should assure the Shibboleth login URLs generated when accessing the host this way will always use the canonical hostname.

Let us also add the following to <VirtualHost 132.181.4.4:443> in shib-vhosts.conf:

RewriteEngine On
RewriteCond %{HTTP_HOST}   !^idp-test\.canterbury\.ac\.nz [NC]
RewriteCond %{HTTP_HOST}   !^$
RewriteRule ^/(.*)         https://idp-test.canterbury.ac.nz/$1 [L,R]

For a lazy-session SP, this redirects all entry URLs to the canonical name, and the server will then always construct login URLs via the application-level WAYF redirector with the canonical hostname.

The above solution, together with UseCanonicalName On, works also when a Shibboleth-protected URL requiring a session is accessed via an incorrect hostname - the RewriteEngine steps in before the access-control module, and the URL redirected to the WAYF server already uses the canonical hostname of the SP.