Shibboleth is an open-source software project that provides SAML and WS-Federation protocol support, and is commonly found throughout the higher education market.  Since it talks standard protocols, AD FS can be configured to grant access to resources protected by Shibboleth.

At the end of this blog post, you'll have a lab machine with an ASP.Net web page protected by Shibboleth and federating to your AD FS identity provider.  We'll start from scratch and quickly build a functioning federation.

This is a great way to explore Shibboleth/AD FS interoperability in a test environment before making the corresponding changes on your live Shibboleth site.

Prerequisites

For simplicity's sake, this post will install Shibboleth onto the same machine as AD FS.  It also assumes the default AD FS identifier is used:  https://your-domain.com/adfs/services/trust

Install Shibboleth

Visit the Shibboleth download site and install the 32-bit or 64-bit SP package as appropriate to your server.  Restart your computer when prompted.

Configure Shibboleth

Edit c:\opt\shibboleth-sp\etc\shibboleth\shibboleth2.xml as follows (bold indicates text you'll need to change to reflect your environment):

  1. Replace <Site id="1" name="sp.example.org"/> with <Site id="1" name="your-domain.com"/>
  2. Replace <Host name="sp.example.org"> with <Host name="your-domain.com">
  3. Enable request/response signing (necessary for single logout to work) by setting the signing attribute of the ApplicationDefaults element to true
  4. Set the entityID attribute of the ApplicationDefaults to https://your-domain.com/shibboleth
  5. Under the Sessions element, change the first SessionInititator example to refer to your AD FS instance by setting the entityID attribute to https://your-domain.com/adfs/services/trust
  6. Tell Shibboleth where to find AD FS's metadata. Under the MetadataProvider element, add:

<MetadataProvider
    type="XML"

    uri="https://your-domain.com/FederationMetadata/2007-06/FederationMetadata.xml"

    backingFilePath="federation-metadata.xml"

    reloadInterval="7200"
/>

        7.  Restart IIS and the Shibboleth Windows service.

a. iisreset
b. net stop shibd_Default
c. net start shibd_Default

Configure AD FS

We'll use PowerShell to add the Shibboleth SP to AD FS.  First, create a file in the current directory called "rules.txt" with the following content.  This rule is authored in the AD FS claims policy language, and configures a SAML NameID to be emitted for the Shibboleth SP.  If you are interested in configuring transient and persistent NameIDs, refer to our previous blog post on the subject.

@RuleTemplate="LdapClaims"

@RuleName="Send E-mail as Name ID"

c:[Type="http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname",
    Issuer == "AD AUTHORITY"]
=> issue(
    store = "Active Directory",
    types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"),
    query = ";mail;{0}",
    param = c.Value); 

Next, run the following PowerShell commands:

  1. Add-PSSnapIn Microsoft.Adfs.PowerShell
  2. Add-ADFSRelyingPartyTrust -Name "Shibboleth SP" -MetadataUrl https://your-domain.com/Shibboleth.sso/Metadata
  3. Set-ADFSRelyingPartyTrust -TargetIdentifier https://your-domain.com/shibboleth -IssuanceTransformRulesFiles rules.txt -SignatureAlgorithm http://www.w3.org/2000/09/xmldsig#rsa-sha1 -IssuanceAuthorizationRules '=> issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true"); '

This will create an AD FS entry for the Shibboleth SP using its metadata.  Additionally, it configures the user's e-mail address to be sent as their Name ID and specifies that Shibboleth will be using the SHA-1 hash algorithm for signing its requests.

Test Shibboleth

Visit https://your-domain.com/secure/.  Shibboleth should redirect you to AD FS for authentication.  Upon success, you'll see... a 404 page.

Create a default page at c:\inetpub\wwwroot\secure\default.aspx, with the following content:

<%@ Page Language="C#" %>

 <html>

<head>

    <title>Shibboleth Echo Page</title>

</head>

<body>

    You are logged in using Shibboleth!

    <hr />

    <table>

        <%

foreach( string key in Request.ServerVariables )

{

    if( key.StartsWith("HTTP_SHIB" ) )

    {

        %>

        <tr>

            <td>

                <%= key %>

            </td>

            <td>

                <%= Request.ServerVariables[ key ] %>

            </td>

        </tr>

        <%

    }

}

        %>

    </table>

    <hr />

    <a href="http://blogs.msdn.com/Shibboleth.sso/Logout">Logout</a>

</body>

</html> 

 Hit refresh.  You'll see the server variables that Shibboleth has populated based on your authentication, as well as a Logout link that you can use to test single logout.  Congratulations, you have a working federation with Shibboleth!

Common Issues

Of course, in the real world, you'll want to send more than just a NameID.  Read on for two common issues you may encounter, and how to work around them.

Attribute Name Format

Shibboleth expects SAML attribute names to have a format of urn:oasis:names:tc:SAML:2.0:attrname-format:uri.  By default, AD FS issues attributes with a name format of urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified.  If there's a mismatch, Shibboleth will ignore the attribute.

You can fix this on the Shibboleth side by editing the attribute-map.xml file.  Rather than:

<Attribute name="urn:oid:2.5.4.42" id="givenName"/>

 Specify the nameFormat attribute to be unspecified:

<Attribute name="urn:oid:2.5.4.42" id="givenName"  nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" />

 Alternately, you can fix this on the AD FS side by writing a custom claim rule to set the name format. Rather than one rule:

c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
=> issue(
    store = "Active Directory",
    types = ("urn:oid:1.3.6.1.4.1.5923.1.1.1.6"),
    query = ";userPrincipalName;{0}",
    param = c.Value);

Write two rules, one to retrieve the claim from AD, the other to issue it with a modified NameFormat:

c:[
    Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname",
    Issuer == "AD AUTHORITY"]
 => add(
    store = "Active Directory",
    types = ("urn:oid:1.3.6.1.4.1.5923.1.1.1.6"),
    query = ";userPrincipalName;{0}",
    param = c.Value);

 c:[
    Type == "urn:oid:1.3.6.1.4.1.5923.1.1.1.6"]
 => issue(
    Type = c.Type,
    Value = c.Value,
    Issuer = c.Issuer,
    Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/attributename"] = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");

If you would like more information about the AD FS policy rules above, have a look at the following TechNet articles for details:

Scoped Attributes

Shibboleth supports "scoped attributes".  These are attributes in the form of "user@scope".  The Shibboleth SP will only process the attribute if the scope portion matches a scope defined in the IdP's metadata.

This is done via a custom Shibboleth extension element.  For details, see the Shibboleth Metadata Profile.

Other Issues?

If you run into issues, you may wish to check Shibboleth's log files, located at

  • var\log\shibd.log
    • This contains SAML-specific log messages.
  • var\log\native.log
    • This contains IIS-specific log messages.

Still stumped? Check out the SP Troubleshooting document at the Internet2 site.