For those who are new the area, there are several open source frameworks available to the developer who is looking to deploy their own Identity Provider (IdP) or Service Provider (SP), such as OpenSAML, Shibboleth (built on top of OpenSAML), Simplesamlphp and Lasso. At this point a couple of definitions would probably be useful.
OASIS provides the following definitions:
- Identity Provider: A kind of service provider that creates, maintains, and manages identity information for principals and provides principal authentication to other service providers within a federation
- Service Provider: A role donned by a system entity where the system entity provides services to principals or other system entities.
Back to OpenSAML, my opinion of it after one week of real hands on use, is that it is quite excellent. Despite the fact that the website is plain and straight talking, its backed up by a great deal of excellent documentation, examples and useful links. If you're like me and you want to start developing a web application using OpenSAML then the section marked 'User's Manual' is for you. The section marked 'Developer's Manual' is for those brave person's who wish to extend the OpenSAML libraries.
After downloading the OpenSAML libraries and importing them into my Java IDE (OpenSAML libraries in C are also available) I started to write a small test app that could decode and unpack an incoming Authentication Request, which would take the form of a XML (SAML) message. SAML messages can be classified as using certain 'bindings', which denotes the method of message transmission. The two most commonly used bindings are HTTP-Post and HTTP-Redirect. For my PoC/test/debug app I wanted to support both bindings, which meant that I needed to be able to accept SAML messages that result from HTTP POST and GET requests. To process messages received from these two channels natively (i.e. without using OpenSAML) is at time non-trivial as URL and Base64 (de/en)coding is required for some bindings, as well as payload (in/de)flation. Using OpenSAML to carryout this task is extremely simple as the two aptly named classes HTTPRedirectDeflateDecoder and HTTPPostDecoder do all the work for you. With a decoded SAML message in hand, and using a couple of supporting utility classes you have access to the unmarshelled SAML message, with all its useful details. The ability to decode, unpack and present an incoming SAML message in itself was (and is) very useful as it provides the ability to compare and contrast SAML tokens generated from different bindings and SPs such as GoogleApps and Force.com. All of this helps to demystify the whole area of SAML message content and communication.
At this point an example would probably come in handy I think. Here's an example of a SAML message that contains a Federated Authentication Request.
Firstly the raw unmarshalled value:
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzYW1scDpBdXRoblJlcXVlc3Q
geG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgSUQ9Im
9pY21hY2VhcG9mZWJwZ29jbG9qbWduZ2RlaGlwa21sb2ZkZmhvZmIiIFZlcnNpb249IjIuMCIgSXN
zdWVJbnN0YW50PSIyMDEwLTExLTAyVDE2OjUzOjA3WiIgUHJvdG9jb2xCaW5kaW5nPSJ1cm46
b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6SFRUUC1QT1NUIiBQcm92aWRlck5h
bWU9Imdvb2dsZS5jb20iIElzUGFzc2l2ZT0iZmFsc2UiIEFzc2VydGlvbkNvbnN1bWVyU2VydmljZV
VSTD0iaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS9hL2NvbXBhbnktZGVtby5jb20vYWNzIj4NCjxzYW
1sOklzc3VlciB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0a
W9uIj5nb29nbGUuY29tL2EvY29tcGFueS1kZW1vLmNvbTwvc2FtbDpJc3N1ZXI+DQo8c2FtbHA6T
mFtZUlEUG9saWN5IEFsbG93Q3JlYXRlPSJ0cnVlIiBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpT
QU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIiAvPg0KPC9zYW1scDpBdXRoblJlcXV
lc3Q+
After passing this value through my decoder app, I received the more readable value of:
Looking at this example message from Google and using even a basic level of SAML knowledge, we can observe several key points regarding their Federated Identity Management solution.
- Google does not sign its outbound Authentication Request messages - The fact that these message are not signed means that it would be quite trivial for a malicious 3rd party to impersonate Google when communicating with a SP
- Google uses the SAML v2.0 standard and not SAML v1.0 or any of the SAML alternatives such as WS-Federation or those from the Liberty Foundation
- The naming format used by Google is unspecified (urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified).
- Google's provider name is 'google.com'
- The Google component that is used to consume SAML messages is Google domain specific, and of the format 'https://www.google.com/a/
/acs'
At this point within my development process and within my app I had a process that could fully interpret and understand an inbound SAML authentication request from Google. The next task was to use this information, and that specified on the Google site to generate a SAML response message that could not only be understood by Google, but also used to carryout Federated SSO for my target user.
All of this and more will be picked up in my next posting on this topic.
Bye for now.