samlgoogle-workspace

SAML authentication request with Google Workspace as the IDP


I have tried importing SAML libraries like SimpleSamlPHP and saml_tools and onelogin_saml, but none of them are simple. They are complicated by all of the options available.

So I'm looking to roll my own dedicated SAML library using the options that I need rather than all of the options available.

I have started with the code from Devish Patel from this website: https://ssojet.com/blog/mastering-saml-implementation-in-php/ which has been super simple to implement into my application.

Now I'm trying to test this using Google Workspace as the IDP and having trouble generating the XML that is acceptable to Google Workspace.

I have configured Google Workspace as the IDP, adding details of the ACS and the EntityID. I have turned on access to this SP for everyone. My PHP code is currently generating this SAML authentication request to Google Workspace.

$xmlstr = '<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
            xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 
            ID="' . $idnumber . '" 
            Version="2.0" 
            ProviderName="' . $sp_meta . '" 
            IssueInstant="' . date('Y-m-d\TH:i:s\Z') . '" 
            Destination="' . $idp_sso_url . '" 
            ProtocolBinding="' . $authn_request_binding . '" 
            AssertionConsumerServiceURL="' . $sp_acs_url . '">
    <saml:Issuer>' . $sp_entity_id . '</saml:Issuer>
    <samlp:NameIDPolicy Format="' . $name_id_format . '" AllowCreate="true"/>
    <samlp:RequestedAuthnContext Comparison="exact">
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
    </samlp:RequestedAuthnContext>
    </samlp:AuthnRequest>';


$doc = new DOMDocument();
$doc->loadXML($xmlstr);
$authnRequest = $doc->saveXML();

error_log("authenticationRequest = " . $authnRequest);

return array(true, $idp_sso_url . '?SAMLRequest=' . base64_encode(gzdeflate($authnRequest)));

The error log statement generates this XML, which is deflated and base64 encoded. I think that's all I need to do.

<?xml version="1.0"?>
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 
                        xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"   
                        ID="_295db7afe835f11035055d8f8b3b34eff04d9ff4" 
                        Version="2.0" 
                        ProviderName="mysamlsp" 
                        IssueInstant="2025-06-19T16:20:21Z"
                        Destination="https://accounts.google.com/o/saml2/idp?idpid=C******sy" 
                        ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" 
                        AssertionConsumerServiceURL="https://mysamlsp.com.au/ui/samlacs.php">
    <saml:Issuer>https://mysamlsp.com.au/ui/login.php?id=71142</saml:Issuer>
    <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true"/>
    <samlp:RequestedAuthnContext Comparison="exact">
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
    </samlp:RequestedAuthnContext>
</samlp:AuthnRequest>

I continue to get this response from Google Workspace: enter image description here

Please help, what is wrong with the XML my code is generating?


Solution

  • The problem I had was this line.

    return array(true, $idp_sso_url . '?SAMLRequest=' . base64_encode(gzdeflate($authnRequest)));
    

    The $idp_sso_url from Google already had a parameter in the URL, so my use of "?SAMLRequest=..." needed to be "&SAMLRequest=..."