This is a simple test SAML SSO server.for Apps and Cloud.
This script acts as your company’s SSO system’s login server. Once configured, if you attempt to access any google property (Cloud, Apps), you need to login via this script first (i.,e the script is acting as an Identity Provider (IdP) while Google is the Service Provider (SP). The script will issue a SAML assertion that google ‘understands’ and will proceed to log you into Cloud or your apps account.
Note: while this SSO server will log you into Cloud and Google Apps, only a google apps resources right now does an automatic redirect to this script. In other words, once this is configured, if you first go to https://mail.google.com/a/<yourdomain.com> you will get redirected to this script and login as its your IdP. However, if you go to https://cloud.google.com/ no such automatic redirect takes place (though you will see the general login page for Google into which if you enter you@yourdomain.com on the login page, you will get redirected to the IdP).
This demonstrates SAML SSO with google properties and is is intended for testing/POC only The script basically runs a SAML IDP within a docker container and this post itself is just a copy of my github page on the same topic:
Login to your google apps admin console (admin.google.com/a/yourdomain.com)
Navigate to Apps SSO Config
set following config depending on where you’re running the IDP:
openssl req -x509 -newkey rsa:2048 -keyout ssl.key -out ssl.crt -days 365 -nodes
Edit your local /etc/hosts file to point sso.yourdomain.com to the system running the container or SSO server
/etc/hosts 127.0.0.1 localhost sso.idpdomain.com
There are several ways to run the image (in order of ease of use):
pull salrashid123/appsso
docker run -t -p 28080:28080 \
-v `pwd`:/app/:ro \
--entrypoint=/app/saml_idp_gsuites.py \
salrashid123/appssso \
--debug \
--cert_file=/app/server.crt \
--key_file=/app/server.key
docker build -t appssso .
docker run -t -p 28080:28080 \
-v `pwd`:/app/:ro \
--entrypoint=/app/saml_idp_gsuites.py \
appssso \
--debug \
--cert_file=/app/server.crt \
--key_file=/app/server.key
python apps.py --debug --use_ssl --cert_file=ssl.crt --key_file=ssl.key --key_blank_pwd
The following compares the SAML Request/Response between the SAML Profiles and original google apps SAML for Domain
"GET /login?SAMLRequest=jZLNbtswEIRfReDdEkmHsUtYNoQEAQykRZCfHnopttTSJiCRKnflNn36Km7SpkGQ9sqdwcx%2By9Xme98VB8wUUqyFKqUoMLrUhrirxd3txWwpNusVQd/pwTYj7%2BM1fh2RuJiMkeyvSS3GHG0CCmQj9EiWnb1p3l9aXUo75MTJpU4UDRFmnqLOUqSxx3yD%2BRAc3l1f1mLPPJCtKnAujZGp3KW067B0qa8eYvIwjWiTh9DWUu/J7OiHZO3NaRLFRcoOj/1q4aEjFMX2vBafvTdeGm9gDnNt0JyqJZj5F1BeL/w7tZxkdAVE4YB/jEQjbiMxRK6FllrN5MlMmlulrV7YE12qhfwkio9P2KYlxSMkezTn53TehgNPSI479MBvyx9eQjvzR6nFyIHvxfo/0PXI0ALDq/xW1fPyv%2B/9YQrbnl%2BlLrj7oum69O0sI/BEivOI/y6sSvWycA%2Bha9o2I5Go1o%2B5f/%2Bs9U8%3D&RelayState=a.AM3QAYaIyyDsckO9IDFAhBCHyLWEqCQCyYHNV4KoG9CCzEhN3TGZ5rnqrPVdRNwD HTTP/1.1" 200 -
Note, if you use SAML profiles, the XML namespace GCP sends is sampl2p:
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="https://accounts.google.com/samlrp/acs?rpid=02hs5gsz0t2f56o" ForceAuthn="false" ID="_ff5f05f5a3a325e5618a53ba1f27f918" IsPassive="false" IssueInstant="2021-04-05T12:27:42.170Z" Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://accounts.google.com/samlrp/metadata?rpid=02hs5gsz0t2f56o</saml2:Issuer>
<saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
</saml2p:AuthnRequest>
<?xml version="1.0" ?>
<saml2p:Response ID="_2da8e2675639cc24fad930b1e3417b3" InResponseTo="_ff5f05f5a3a325e5618a53ba1f27f918" IssueInstant="2021-04-05T12:27:45Z" Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">authn.py</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#_2da8e2675639cc24fad930b1e3417b3">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>NN4YrOUpz+g3aGKohbBSDAfOJTM=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>vQruO+8EzZUqHbkmtpKJe9sNGglrGBZGkMvJu0TY+ATCYxMmPI6XIHt1HVj9Ejh2
jZet9pTQPAKrCqE70Ueo8aoryA16PnaqxWT0yKTIP7Ykt5tWoV8G2+B0sT7wB7Yi
2rXJwZUJ7w0YkmOZ7LOMPrzUr6HSDcmtwzTJBffLMUlvle0snWO6AC3hUWsvy8g/
q3DumXcDnbisTsB3hhGJGZ+KG13Cnilbp8P0nbbV5EN9vOV2PcGJRaD22cWNvsgA
dKEPiMJscHFyafnxhWHCS+ceJM/tcWDMNwkifWhqmQQWZvJ/4eT4uQaIrZluu6jG
haYGt3h5t130G4N2eFfXGQ==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIEQDCCAyigAwIBAgIBDzANBgkqhkiG9w0BAQUFADBXMQswCQYDVQQGEwJVUzEP
MA0GA1UECgwGR29vZ2xlMRMwEQYDVQQLDApFbnRlcnByaXNlMSIwIAYDVQQDDBlF
bnRlcnByaXNlIFN1Ym9yZGluYXRlIENBMB4XDTIwMTAzMTIwMjIxNVoXDTIyMTAz
MTIwMjIxNVowVDELMAkGA1UEBhMCVVMxDzANBgNVBAoMBkdvb2dsZTETMBEGA1UE
CwwKRW50ZXJwcmlzZTEfMB0GA1UEAwwWc2VydmVyLmVzb2RlbW9hcHAyLmNvbTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMZThbWkUvD8wxzP/v/t918Z
0fhDYgSrow75G1kIbUf5Z3qG+l0AyLadIo3SqN3ENQYf2+O1VP9Hk90tyvCSiGqj
XJLCLXdrwLLqHoqFDxwm3bQ0/AlOIpmilS++BdHUew0HfqZq9lJOFPAF3EtLLPaE
0eRbA2HguHe4q/7jIIr999vYuafCtetrzIBI8ke9+S2VvPPw+ni2KZvmTb1+DnIq
q7QX/t92Y9RW1UgeXqvc/LbYwnIfSyCpea1IvHILup+eQ/R2aeIgzFrDbuS4ULrx
dJrMu4UXXPJMbw7xSOAdhJoX+uky08bR3pbUbt6wNwwjuDLNLBIdlYZK6seLQRsC
AwEAAaOCARgwggEUMA4GA1UdDwEB/wQEAwIHgDAJBgNVHRMEAjAAMBMGA1UdJQQM
MAoGCCsGAQUFBwMBMB0GA1UdDgQWBBQ/ZBWqbeL7spn5xkS9awVgZ5L1ITAfBgNV
HSMEGDAWgBS/4RzwIkiP/DvPXdntrohwId/dhjBEBggrBgEFBQcBAQQ4MDYwNAYI
KwYBBQUHMAKGKGh0dHA6Ly9wa2kuZXNvZGVtb2FwcDIuY29tL2NhL3Rscy1jYS5j
ZXIwOQYDVR0fBDIwMDAuoCygKoYoaHR0cDovL3BraS5lc29kZW1vYXBwMi5jb20v
Y2EvdGxzLWNhLmNybDAhBgNVHREEGjAYghZzZXJ2ZXIuZXNvZGVtb2FwcDIuY29t
MA0GCSqGSIb3DQEBBQUAA4IBAQAK2KMOjOXV88sqL0KW41uU4C1yHd0zwsYB1G3d
q5I46r+YO4si5y81DcRmAgnDDFF/fc7E7RgLCYNYAf2WxUmsqSQgo27+bWs9EGlP
v86pnUxOk4M2P57fQzU28sA9D86tir3G5Bh0IRQcgQ7E6ty10nOiNuQYkJFSuwyw
DgNs7Ftvhd9xbFYy2OZqAjsBk7bFa06FVvVVUFaBEPnHB33hO56iS83VsO4M18SS
ZlFKnQjJhgj8mLFEZctFvKisubcwi5mBuSqGZVAw8Ma7DDjlosGWIWqiGV/f6uS6
2uk6/Vjor+QwjTxhqvTIoDwXIU4gm5b3wMlMCv7ImTHv5iWC</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</saml2p:Status>
<saml2:Assertion ID="_aae9f3deca29e911d55308ff15b9cc7" IssueInstant="2021-04-05T12:27:45Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">authn.py</saml2:Issuer>
<saml2:Subject>
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">user1@esodemoapp2.com</saml2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData InResponseTo="_ff5f05f5a3a325e5618a53ba1f27f918" NotOnOrAfter="2021-04-05T13:17:45Z" Recipient="https://accounts.google.com/samlrp/acs?rpid=02hs5gsz0t2f56o"/>
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:Conditions NotBefore="2021-04-05T12:27:45Z" NotOnOrAfter="2021-04-05T13:17:45Z">
<saml2:AudienceRestriction>
<saml2:Audience>https://accounts.google.com/samlrp/metadata?rpid=02hs5gsz0t2f56o</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AuthnStatement AuthnInstant="2021-04-05T12:27:45Z" SessionIndex="_aae9f3deca29e911d55308ff15b9cc7">
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
</saml2:Assertion>
</saml2p:Response>
<?xml version="1.0" encoding="UTF-8"?>
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="dieoibobioiggldaoaiemkakcbpffhbdmppeoode" Version="2.0" IssueInstant="2021-04-05T12:30:40Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" ProviderName="google.com" IsPassive="false" AssertionConsumerServiceURL="https://www.google.com/a/esodemoapp2.com/acs">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">google.com</saml:Issuer>
<samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/>
</samlp:AuthnRequest>
<?xml version="1.0" ?>
<samlp:Response Destination="https://www.google.com/a/esodemoapp2.com/acs" ID="_42dfc2173138837ac02982337a6e33a" InResponseTo="dieoibobioiggldaoaiemkakcbpffhbdmppeoode" IssueInstant="2021-04-05T12:30:44Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<saml:Issuer>authn.py</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#_42dfc2173138837ac02982337a6e33a">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>7GHJw5xRX1CSq9PuXN8cWttIiKI=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>ur4rnmw9MLoZzfmOR0zSWZtYWmUZ524vyve7G6NjAKCQfXTnMceLhatPKSp+dm13
vBpiYfFQldsgjN1882g3Dv6EMkul9MM3ftxJI2i185XN+hkb1AM6CzHKbgTlfgiw
1KdaStkJOimY1PMZfI/J5E7HSeOnxjbGf7ZhYXM0nGywxL78s+OhT/26YOoV+5Gp
fMDl+S/yMJI+K5owh/vOkE3uv160qoANGHBBiSxMSxSmwNMt3ZoRFA4qZYbqLm9e
IOmK0HNldK/Gj/FdqfL7mhHus7WqfeC5UoV/aHzEgc5DUeppJhee7d3zF00cTjiT
i3j0tcLl4qmQKJ8mGzWcfQ==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIEQDCCAyigAwIBAgIBDzANBgkqhkiG9w0BAQUFADBXMQswCQYDVQQGEwJVUzEP
MA0GA1UECgwGR29vZ2xlMRMwEQYDVQQLDApFbnRlcnByaXNlMSIwIAYDVQQDDBlF
bnRlcnByaXNlIFN1Ym9yZGluYXRlIENBMB4XDTIwMTAzMTIwMjIxNVoXDTIyMTAz
MTIwMjIxNVowVDELMAkGA1UEBhMCVVMxDzANBgNVBAoMBkdvb2dsZTETMBEGA1UE
CwwKRW50ZXJwcmlzZTEfMB0GA1UEAwwWc2VydmVyLmVzb2RlbW9hcHAyLmNvbTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMZThbWkUvD8wxzP/v/t918Z
0fhDYgSrow75G1kIbUf5Z3qG+l0AyLadIo3SqN3ENQYf2+O1VP9Hk90tyvCSiGqj
XJLCLXdrwLLqHoqFDxwm3bQ0/AlOIpmilS++BdHUew0HfqZq9lJOFPAF3EtLLPaE
0eRbA2HguHe4q/7jIIr999vYuafCtetrzIBI8ke9+S2VvPPw+ni2KZvmTb1+DnIq
q7QX/t92Y9RW1UgeXqvc/LbYwnIfSyCpea1IvHILup+eQ/R2aeIgzFrDbuS4ULrx
dJrMu4UXXPJMbw7xSOAdhJoX+uky08bR3pbUbt6wNwwjuDLNLBIdlYZK6seLQRsC
AwEAAaOCARgwggEUMA4GA1UdDwEB/wQEAwIHgDAJBgNVHRMEAjAAMBMGA1UdJQQM
MAoGCCsGAQUFBwMBMB0GA1UdDgQWBBQ/ZBWqbeL7spn5xkS9awVgZ5L1ITAfBgNV
HSMEGDAWgBS/4RzwIkiP/DvPXdntrohwId/dhjBEBggrBgEFBQcBAQQ4MDYwNAYI
KwYBBQUHMAKGKGh0dHA6Ly9wa2kuZXNvZGVtb2FwcDIuY29tL2NhL3Rscy1jYS5j
ZXIwOQYDVR0fBDIwMDAuoCygKoYoaHR0cDovL3BraS5lc29kZW1vYXBwMi5jb20v
Y2EvdGxzLWNhLmNybDAhBgNVHREEGjAYghZzZXJ2ZXIuZXNvZGVtb2FwcDIuY29t
MA0GCSqGSIb3DQEBBQUAA4IBAQAK2KMOjOXV88sqL0KW41uU4C1yHd0zwsYB1G3d
q5I46r+YO4si5y81DcRmAgnDDFF/fc7E7RgLCYNYAf2WxUmsqSQgo27+bWs9EGlP
v86pnUxOk4M2P57fQzU28sA9D86tir3G5Bh0IRQcgQ7E6ty10nOiNuQYkJFSuwyw
DgNs7Ftvhd9xbFYy2OZqAjsBk7bFa06FVvVVUFaBEPnHB33hO56iS83VsO4M18SS
ZlFKnQjJhgj8mLFEZctFvKisubcwi5mBuSqGZVAw8Ma7DDjlosGWIWqiGV/f6uS6
2uk6/Vjor+QwjTxhqvTIoDwXIU4gm5b3wMlMCv7ImTHv5iWC</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ID="_dc3675c3620ba1f20e7feea6d174b8b" IssueInstant="2021-04-05T12:30:44Z" Version="2.0">
<saml:Issuer>authn.py</saml:Issuer>
<saml:Subject>
<saml:NameID>user1@esodemoapp2.com</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="dieoibobioiggldaoaiemkakcbpffhbdmppeoode" NotOnOrAfter="2021-04-05T13:20:44Z" Recipient="https://www.google.com/a/esodemoapp2.com/acs"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2021-04-05T12:30:44Z" NotOnOrAfter="2021-04-05T13:20:44Z">
<saml:AudienceRestriction>
<saml:Audience>google.com</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2021-04-05T12:30:44Z" SessionIndex="_dc3675c3620ba1f20e7feea6d174b8b">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
</samlp:Response>
This site supports webmentions. Send me a mention via this form.