NAME
Google::SAML::Response - Generate signed XML documents as SAML responses for Google's SSO implementation
VERSION
You are currently reading the documentation for version 0.04
DESCRIPTION
Google::SAML::Response can be used to generate a signed xml document that is needed for logging your users into Google using SSO.
For example, you have some sort of application that authenticates users such as a web application. Your users should be able to use some sort of Google service such as Google mail. Now when using SSO with your Google partner account, Google will redirect users to a URL that you can define. Behind this URL, you can have a script that can authenticate users in your original framework, generate a SAML::Response for Google that you send to your users who then submit it to Google. If everything works, users will then be logged into a Google account and they don't even have to know their usernames or passwords.
SYNOPSIS
use Google::SAML::Response;
use CGI;
# get SAMLRequest parameter:
my $request = CGI->new()->param('SAMLRequest');
# authenticate user
...
# find our user's login for Google
...
# Generate SAML::Response
my $saml = Google::SAML::Response::new( key = $key, login => $login, request => $request );
my $xml = $saml->generate_signed_xml();
# Alternatively, send a HTML page to the client that will redirect
# her to Google. You have to extract the RelayState param from the cgi
# environment first.
print $saml->get_google_form( $relayState );
PREREQUISITES
You will need the following modules installed:
RESOURCES
- XML-Signature Syntax and Processing
- Google-Documentation on SSO and SAML
-
http://code.google.com/apis/apps/sso/saml_reference_implementation.html
- XML Security Library
METHODS
new
Creates a new object and needs to have all parameters needed to generate the signed xml later on. Parameters are passed in as a hash-reference.
Required parameters
request
The SAML request, base64-encoded and all, just as retrieved from the GET request your user contacted you with
key
The path to your private key that will be used to sign the response. Currently, only RSA keys without pass phrases are supported.
login
Your user's login name with Google
Optional parameters
ttl
Time to live: Number of seconds your response should be valid. Default is two minutes.
canonicalizer
The name of the module that will be used to canonicalize parts of our xml. Currently, XML::Canonical and XML::CanonicalizeXML are supported. XML::CanonicalizeXML is the default.
get_response_xml
Generate the signed response xml and return it as a string
The method does what the w3c tells us to do (http://www.w3.org/TR/xmldsig-core/#sec-CoreGeneration):
3.1.1 Reference Generation
For each data object being signed:
1. Apply the Transforms, as determined by the application, to the data object.
2. Calculate the digest value over the resulting data object.
3. Create a Reference element, including the (optional) identification of the data object, any (optional) transform elements, the digest algorithm and the DigestValue. (Note, it is the canonical form of these references that are signed in 3.1.2 and validated in 3.2.1 .)
3.1.2 Signature Generation
1. Create SignedInfo element with SignatureMethod, CanonicalizationMethod and Reference(s).
2. Canonicalize and then calculate the SignatureValue over SignedInfo based on algorithms specified in SignedInfo.
3. Construct the Signature element that includes SignedInfo, Object(s) (if desired, encoding may be different than that used for signing), KeyInfo (if required), and SignatureValue.
get_google_form
This function will give you a complete HTML page (including the HTTP headers) that you can send to clients to have them redirected to Google.
After all the hi-tec stuff Google wants us to do to parse their request and generate a response, this is where it gets low-tec and messy. We are supposed to give clients a html page that contains a hidden form that uses Javascript to post that form to Google. Ugly, but it works. The form will contain a textarea containing the response xml and a textarea containing the relay state.
Hence the only required argument: the RelayState parameter out of the user's GET request
REMARKS
Coming up with a valid response for a SAMLRequest is quite tricky. The simplest way to go is to use the xmlsec1 program distributed with the XML Security Library. Google seems to use that program itself. However, I wanted to have a Perlish way of comming up with the response. Testing your computed response is best done against xmlsec1: If your response is stored in the file test.xml, you can simply do:
xmlsec1 --verify --store-references --store-signatures test.xml > debug.txt
This will give you a file debug.txt with lots of information, most importantly it will give you the canonical xml versions of your response and the References element. If your canonical xml of these two elements isn't exactly like the one in debug.txt, your response will not be valid.
This brings us to another issue: XML-canonicalization. There are currently two modules on CPAN that promise to do the work for you: XML::CanonicalizeXML and XML::Canonical. Both can be used with Google::SAML::Response, however the default is to use the former because it is much easier to install. However, the latter's interface is much cleaner and Perl-like than the interface of the former.
XML::Canonical uses XML::GDOME which has a Makefile.PL that begs to be hacked because it insists on using the version of gdome that was available when Makefile.PL was written (2003) and then it still doesn't install without force. XML::CanonicalizeXML is much easier to install, you just have to have the libxml development files installed so it will compile.
TODO
Add support for DSA keys
Add support for encrypted keys
AUTHOR
Manni Heumann (saml at lxxi dot org)
LICENSE
Copyright (c) 2008 Manni Heumann. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.