I have a client who acts as a Shibboleth Service Provider (SP), and the corresponding Identity Provider (IdP) needed to update some of their information, so I had to spend a few hours debugging shibboleth again this morning.
The punchline: in the metadata for an IdP, there are TWO places you need to specify the scope of the IdP, once in the
<IDPSSODescriptor> to cover authentication, and once later in the
<AttributeAuthorityDescriptor> to cover any attributes.
Shibboleth is all about trust, and the lack thereof. The SP and IdP share a few keys, and then each maintain their own configuration files specifying how much information to trust. When a user logs in, they get bounced from SP->IdP to authenticate, then again from IdP -> SP with an auth token. From there, the SP can assume an authenticated user. If the SP wants any more information about the user (say, a username), it can make SOAP calls to the IdP requesting more attributes. The IdP checks it’s config files to see how many attributes to release to that particular SP, and sends back the attributes. The SP doesn’t trust the IdP on it’s word, so the SP checks it’s config files to validate that it can accept these attributes from this IdP. This is where I ran into a problem, getting an error like:
attribute (username) scope (foo.bar.edu) not accepted
This brings up another aspected of attributes, the scope. An attribute’s scope seems somewhat akin to a namespace to me, it’s a way of grouping related attributes and prevent name conflicts between attributes. In my case, my IdP was “bar.edu”, and my SP was configured to accept the username attribute from any site with any value (in my AAP.xml). However, the IdP was returning the username scoped under a different domain, so the SP, being a paranoid creature, assumes the IdP is trying to falsify information and refused the attribute. To convince the SP to accept the different scope, you have to change the metadata for the IdP, and specify that it is allowed to provide attributes in the new scope. Unfortunately for me, there are 2 kinds of scopes you can change:
- Scope of the initial authentication
- Scope of the attributes
There are both children of
<EntityDescriptor>. This led to a frustrating morning of restarting IIS (because you need to restart everything under the sun for the configuration to get reloaded), and not seeing any change. There are many ways to alter your attribute policy, and along to way to discovering the second place to specify scope I ran across another error message:
attribute (username) value (my-user) could not be validated by policy, rejecting it
This seemed to happen when my SP config tried to treat the username as an unscoped attribute. You can’t just ignore the scope of an attribute if the IdP is sending one.
The end solution is to add another
<shibmeta:Scope> specification to the attributes configuration section in the IdP’s metadata:
<AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol"> <Extensions> <shibmeta:Scope xmlns:shibmeta="urn:mace:shibboleth:metadata:1.0" regexp="false">bar.edu</shibmeta:Scope> <shibmeta:Scope xmlns:shibmeta="urn:mace:shibboleth:metadata:1.0" regexp="false">foo.bar.edu</shibmeta:Scope> </Extensions> ...