Single Sign On to Google using OpenSSO
By steffo on Mar 17, 2008
Google has a SAML 2 capable single-sign-on service by which you can use Google as a service provider (SP). Google also provides a sample demo application. Rather than using Liberty Alliance's circle-of-trust model, Google uses a peered structure: if Google's SSO service (SP) receives a SAML response, it checks the signature of that request. If the signature is valid, the SAML assertion will be accepted.
Trying to use Google's demo code with OpenSSO as an identity provider (IDP) requires some tweaks.Step 1: Making OpenSSO to accept Google's SAML request
- The SAML request sent out by Google's demo code cannot be understood by OpenSSO due to a compression (deflate) problem (from what I saw in the code, it seems that Google inflates according to RFC 1950 but SAML specification dictates RFC 1951 and that's also what OpenSSO implements). All you need to do to replace Google's RequestUtil.encodeMessage(String) code with OpenSSO's SAML2Utils.encodeForRedirect(String).
- Google's code uses a simple template for constructing the SAML request. In fact too simple for OpenSSO. Add a few XML elements to the AuthnRequestTemplate.xml
- Point ssoURL in CreateRequestServlet.doPost(HttpServletRequest, HttpServletResponse) to you OpenSSO instance (e.g. http://localhost:8080/opensso/idpSSOFederate/metaAlias/idp where 'idp' is your IDP entity.
<?xml version="1.0" encoding="UTF-8"?> <AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:protocol file:/Documentation/Federation-SAML-Liberty/SAML%202.0/XSD/saml-2.0-os-xsd/saml-schema-protocol-2.0.xsd" ID="<AUTHN_ID>" Version="2.0" IssueInstant="<ISSUE_INSTANT>" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" ProviderName="<PROVIDER_NAME>" ForceAuthn="true" AssertionConsumerServiceURL="<ACS_URL>"> <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion" format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"> google </Issuer> <Subject xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> <NameID>google</NameID> </Subject> </AuthnRequest>
- Import Google's sample private key to Java keystore. Since keytool cannot import arbitrary private keys, I convert Google's keys to PKCS#12 and then use one of the PKCS12Import classes (source can be found on the net) to import the key to JKS.
- Since Google's keys are DSA keys and are only good for signing, but not for encrypting you need to tell OpenSSO via browser GUI (Service Configuration > Global > Common Federation Configuration) to sign, but not to encrypt the SAML response.
- You also need an account mapper that generates the SAML response message. Pat Patterson posted a sample on the OpenSSO mailing list (check the OpenSSO archives). Google wants the email address as an identity ('email@example.com' is the default one in case you don't own a Google apps premier account). You can use Pat's version out of the box if your OpenSSO user has IDfirstname.lastname@example.org' or you can extend Pat's code returning the user's email adress (e.g. via OpenSSO's DataStoreProvider.getAttribute(String, String)).