I have created a realm in Keycloak named SAML-Demo-Py
In the realm I have created a SAML client with these configuration
{
"clientId": "http://localhost:8081/python-app",
"name": "test-client-saml",
"description": "",
"rootUrl": "",
"adminUrl": "http://localhost:8081/cgi-bin/saml-consumer.py",
"baseUrl": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"http://localhost:8081/cgi-bin/saml-consumer.py"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": true,
"protocol": "saml",
"attributes": {
"saml_assertion_consumer_url_redirect": "http://localhost:8081/cgi-bin/saml-consumer.py",
"saml.force.post.binding": "true",
"saml.server.signature.keyinfo.ext": "false",
"saml.signing.certificate": "MIICzzCCAbcCBgGDSplRlDANBgkqhkiG9w0BAQsFADArMSkwJwYDVQQDDCBodHRwOi8vbG9jYWxob3N0OjgwODEvcHl0aG9uLWFwcDAeFw0yMjA5MTcwODM2NDVaFw0zMjA5MTcwODM4MjVaMCsxKTAnBgNVBAMMIGh0dHA6Ly9sb2NhbGhvc3Q6ODA4MS9weXRob24tYXBwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAve0sgrdPWvcKiRJ5UPcpa301aiIO7F7KDKnMDtxgY2EE47z8XS5TUvvySa75L0phxZQv+iqYSV1HlUkgJQiax3fg7JgxJ+BY3ss9Dz/m9x7stErFoMXeH+Bhdk9H7hUojlRqxn8qU7ZwInENvw8hlzTgouc5hqqBaQybXqtlmJi6HWAH/3Ck6jCd+P6pjIaGrQpYxpmpmPKbhRnovZWgL6KqdnoEl1thEcPAEbXE7HiB6h4z9HdF2EWx/8U7HE/qCq2m2lPsKn2OnJk2ejDqa5SyTBXRqeqS8sG70VXrotEtJVVuPJCFvGy8r7mq0bVX/83y+PyEpppsJMMtockdgwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBEDptd2Goi1XFKur3dpRHyOW9zxs96gGGllrcnQZCtZjVEb31Jibr0HFDftHR22hQV1mbQLokNk8k0on7tJvsOIdXv3459gkZyouYSmYpDTvfCi3YUgdxVrDiHzwaN6uIjqXeDeI08LmH2xDZwac46vqJyqx3QI/r84qmWR2Nil/7DnJegVWyr961GWm0HH6BpweZZ5QbEw0UHihqWDthgX4BAmVnRPm9fHebIa3/7AUqodh8hoRDJcaDiyLB+V8nUPD6vLwgFgiLSqLSPaJ0OSzBvz3cpNLL1PVkFVaoQZ7W3FX6Ruvz0Bj/piQ+h2fnX4NMkj33f6CyhJTGSfbnk",
"saml$server$signature$keyinfo$ext": "false",
"saml.signature.algorithm": "RSA_SHA256",
"saml.client.signature": "false",
"saml.force.name.id.format": "false",
"saml.signing.private.key": "MIIEowIBAAKCAQEAve0sgrdPWvcKiRJ5UPcpa301aiIO7F7KDKnMDtxgY2EE47z8XS5TUvvySa75L0phxZQv+iqYSV1HlUkgJQiax3fg7JgxJ+BY3ss9Dz/m9x7stErFoMXeH+Bhdk9H7hUojlRqxn8qU7ZwInENvw8hlzTgouc5hqqBaQybXqtlmJi6HWAH/3Ck6jCd+P6pjIaGrQpYxpmpmPKbhRnovZWgL6KqdnoEl1thEcPAEbXE7HiB6h4z9HdF2EWx/8U7HE/qCq2m2lPsKn2OnJk2ejDqa5SyTBXRqeqS8sG70VXrotEtJVVuPJCFvGy8r7mq0bVX/83y+PyEpppsJMMtockdgwIDAQABAoIBABjRKm1ELarZt/c0QkTpnvBsMnQVUjThp+4iq8bPVgr2TPDDK4izenDP+hdVtTrQMdli5Sf/s9l2RlnD7d7Y8nyY9fuEYXvv7Tzjeq2I8JGe6VgfoxZAdKdepu2SK3h5LEz4y+D3Ed1Ra/KcKisqe32qC6ZNp28ozXMgEhc7NzHKnOxKA0IXFzuT6cDJgJ8TQfa2K9dGgjEE9GTCCxnZEvdf17sEc4zVMJDDcE4Rorv0mZeN1QRXVSpnW1q0vFh1CvH1H9oBCUey8cElQybARTDbMJJWgHCdd29EbilmlyB4TFI34tcaKZUlvL3sT8fvRyV6yLL0M0mqVWYxhu24naUCgYEA/WKH8G6SsM+LhC2oVJWUSDicpDNNEi2Av2FZOSg7Vbqj53/t69kSPWv0Rp0o7Bz55xwxH+n6PjUEvHyiS3UBIW6kS81av1H8Gle/1XpopHEY4aX47KCdF1Wc0yq8l5ii+oFZt3GcS1egDFPiQgyo2lhlrrQ4mckcSZF3pdd8UTUCgYEAv+L6qdXxPZvyzRgsRfhmVl8FKdKPYFqBWQgh2Lx21J16T8jRhjFfJP6NNi2JupWrQB2JdA5sivx81GMxExo5j8P1VQm/g/c3I2bxb1kYDE77x6KJzmr0i7hK0SEGCcP51EdVpjtPzcdG3st3GT5UClvZ+rTfO87e6n4pdlMUgtcCgYBUre8cTPe9Gz9XByMwUWTi1fiTb4mcP5S9YL0+utFJjzxji39pyHuuBzv1tWQNtIlX0TYhokI9M97HVyet7AZas+04YAKp2a5U52p235fFDP7xulP8UJjvSW9Fqwyn5RzidwQSqGdBTqFwPUBqLmznu48P2a7oxisr8u93fxJO2QKBgG0fkdl/139n7n6AXr0z9E7uHquYGP18us5893KgSxvCqsowtCcScL9DG99Rql+3ufnuUjrz8PpheEP4XPI2GcIOeLhxoL5Vmr/BTVA7ZJerWzg+0QvYe1Xx6mpf02U+VBdKsgSk+k9WIpGVOBfdAEIb1izjK4iBrve/46hsut9lAoGBAKeKxXlH45BTuRg/Rcp60TTV4i+Aed0ApTmvYU22XasXRfrFsauLaxUkCP0x0hvdVx+cR37Jo9Nfw9DmplzHLVMI6STzracLuhjf0HKVS6XSJa5l4VpsmkJaWxyqdrm91OXnOOizTf6pOoRFoFI21u7ZKqMoEcaqrCOIwqv21qpa",
"saml.allow.ecp.flow": "false",
"saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer": "NONE",
"saml.assertion.signature": "true",
"saml.encrypt": "false",
"login_theme": "keycloak",
"saml_assertion_consumer_url_post": "http://localhost:8081/cgi-bin/saml-consumer.py",
"saml$server$signature": "true",
"saml.server.signature": "true",
"saml.artifact.binding.identifier": "90y02x5M6keohgaOI7l3D0ZpdfU=",
"saml$server$signature$keyinfo$xmlSigKeyInfoKeyNameTransformer": "NONE",
"saml.artifact.binding": "false",
"saml_force_name_id_format": "false",
"saml.authnstatement": "true",
"display.on.consent.screen": "false",
"saml_name_id_format": "username",
"saml.onetimeuse.condition": "false",
"saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"role_list"
],
"optionalClientScopes": [],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
I have a running python dummy app which will act as ACS.
This is the SAML Request which will be send from the browser in the form of
<IDP-sso-url>?SAMLRequest=<encoded-same-request>
which results in
http://localhost:8080/realms/SAML-Demp-Py?SAMLRequest=lVLLTsMwEPyVyHfXSZpCayWVSiNEJEBRKRy4INdZqIVjB6%2FD4%2B9xUpDKBcHNK8%2FMzow2R9Hqjq96vzcbeOkBffTeaoN8%2FChI7wy3AhVyI1pA7iW%2FWV1d8nQS885Zb6XV5ED5HSwQwXllDTla8GfK6vu5tgb7FtwNuFcl4XZzWZC99x1nTFsp9N6i5%2FN4HjMHQrfIBjVaQtvR%2BoPtnH0Gx4bVVDUd9SEvA9N0VhlPojKMyohhzz9USXRunYSxw4I8Co1AoqosSFU%2BxMluOltAQuOTpKEZwIyKTIYxyzKxkDJtxGkAI%2FZQGfTC%2BIKkcZrSeEGT022S8GnM05PJdDG%2FJ1H9VfiZMo0yT7%2B3tzuAkF9stzXdQKMcyBDyDhyOAQOILPOhCz4acMs%2FR87ZMS0%2FHNF1sFCVtdVKfkQrre3bOlA9FMS7HsaWWhHy1YMB9BAaZ8uD0s8LXH4C&RelayState=9UITFKRCV-uUX7vdyNF6xIEybOVX2uDNZVohLi5OenU.q8U2Lp-_Lg8.http%3A%2F%2Flocalhost%3A8081%2Fpython-app
This is the request before encoding
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="http://localhost:8081/cgi-bin/saml-consumer.py"
Destination="http://localhost:8080/realms/SAML-Demp-Py/protocol/saml"
ID="1234"
IssueInstant="2021-09-17T18:41:20.295Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml2:Issuer
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:8081/python-app
</saml2:Issuer>
</saml2p:AuthnRequest>
Now once past this in the url I don't see the keycloak login screen. Instead the url in the browser is still the same as above and I see this json in the body of the page
{"realm":"SAML-Demp-Py","public_key":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvvoRDqFxcnJAmISv4qequAJ4w1dubE47Z2RStqVQ7oUZaUPO2magxvfa8CyaEwHuySkn42NjrafVMhZp/0gBVtsVW4uwNJCMXjvv8Tfbd4qUtVo50mEgGIpJRsm5RPXUJX2q1Yz/jX+U2vTfutEIDpRZGF6PtHt/tavuGt+qohpRycTWFvcEU7LuVu7Sj7AaOBNpgGSITUEYc09+JwrWcbenhrBZq9mJ5hgCw/0TU+HcwCIi1XgUVrzZ6OG0DwE702ezuDP2Nbs78U0w6tHUj+B1+p/TAntIg39CiwHHL3kIcwwJpHiJmeLNTlwlQm+Ny3w9LmP09dPAjMm2lw1qywIDAQAB","token-service":"http://localhost:8080/realms/SAML-Demp-Py/protocol/openid-connect","account-service":"http://localhost:8080/realms/SAML-Demp-Py/account","tokens-not-before":0}
You are using wrong endpoint. It is:
http://localhost:8080/realms/SAML-Demp-Py/protocol/saml?SAMLRequest=<encoded-saml-request>
instead of:
http://localhost:8080/realms/SAML-Demp-Py?SAMLRequest=<encoded-saml-request>