SAML assertion base64 decode

deniska
Participant V

Hi team,

I'm implementing SAML authentication process, where user gets redirected from another server 302 (with the location of my proxy) and query param of saml assertion, e.g.:

https://myserv/v1/proxy?saml=[big string of base64 encoded]

Here I have some questions:

- I want to extract the request.queryparam.saml var and base64 decode it. For that, I'm using base64 template function .

- However, I noticed that if SAML encoded in base64 contains "+" character in the string, function fails.

My SAML example:

PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c2FtbHA6UmVzcG9uc2UgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeGJiYWJkZTMxLWM5MTUtNzViNS0yM2Y0LTU5NDE1NzlmZDg5MiIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMTQtMDctMTdUMDE6MDE6NDhaIiBEZXN0aW5hdGlvbj0iaHR0cDovL3NwLmV4YW1wbGUuY29tL2RlbW8xL2luZGV4LnBocD9hY3MiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fNGZlZTNiMDQ2Mzk1YzRlNzUxMDExZTk3Zjg5MDBiNTI3M2Q1NjY4NSI+DQogIDxzYW1sOklzc3Vlcj5odHRwOi8vaWRwLmV4YW1wbGUuY29tL21ldGFkYXRhLnBocDwvc2FtbDpJc3N1ZXI+PGRzOlNpZ25hdHVyZSB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+DQogIDxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+DQogICAgPGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNyc2Etc2hhMSIvPg0KICA8ZHM6UmVmZXJlbmNlIFVSST0iI3BmeGJiYWJkZTMxLWM5MTUtNzViNS0yM2Y0LTU5NDE1NzlmZDg5MiI+PGRzOlRyYW5zZm9ybXM+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjwvZHM6VHJhbnNmb3Jtcz48ZHM6RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3NoYTEiLz48ZHM6RGlnZXN0VmFsdWU+YjJrZk55Z1QwelpXc1BURTZXN20vU0dEd0lrPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5aYUJTU1hyS0QrRElMTkl1cTJPdWFOU1IrcDVSZ1pIRWIzV28ybWlUWElhelE2ditrRDh6MXBiOXk0c294S2FXT0tuNkZFTFY3ZCtHc2wxVkRqSzNhS3dDd2NzVWIvNkZXVTB6M2hBcGFKdTh2TWZYSVZaYUJnUE04bC9rZC9PMG53UWtqZ2NTZEZCTXpZa0VFQW9jSURSRkJxclpmMnd6cXVmREJUeWh0ZXM9PC9kczpTaWduYXR1cmVWYWx1ZT4NCjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUNMakNDQVplZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRMEZBREEwTVFzd0NRWURWUVFHRXdKMWN6RUxNQWtHQTFVRUNBd0NZWE14Q3pBSkJnTlZCQW9NQW1Gek1Rc3dDUVlEVlFRRERBSnpZVEFlRncweE9UQTJNVGN5TWpJeU1qQmFGdzB5TURBMk1UWXlNakl5TWpCYU1EUXhDekFKQmdOVkJBWVRBblZ6TVFzd0NRWURWUVFJREFKaGN6RUxNQWtHQTFVRUNnd0NZWE14Q3pBSkJnTlZCQU1NQW5OaE1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRRGhhY2NNdUFsUUlwcVNYT1N3VFZ3czlxNWdMK0RsNEhkajk0TjluZW9kN0ExcUhGSEh2LzVjMUlUaTJaK3Y1cUJ2eWF0ZlZoYS9OVWJ1bUZVbEs3TVY0Y3ZqdWI4cjArUkR5Y2hLc01NUSt4NndBSEcwcE0wNStiNUk0cyszZE9YM3RQRTlZNkpYYmkwUzh2NDUxcnJmT1REWEYzTmpZN2tkQzNvRG4vSmpnd0lEQVFBQm8xQXdUakFkQmdOVkhRNEVGZ1FVUnNncmNMM1h0WEhOQVZMK1lXR1lYQ1hoYXIwd0h3WURWUjBqQkJnd0ZvQVVSc2dyY0wzWHRYSE5BVkwrWVdHWVhDWGhhcjB3REFZRFZSMFRCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUTBGQUFPQmdRQXc1UlNLZUczY1ZDdWI4ZFh1dzdPVzhvakJOT2gxZHVXa2ZaS0ZMdGZtQWdLVlA2ODFCaUFQaXlVZ1RXeERXVlVXM3h3aXNmVHl6QjhVbHRrK0hOWG4xeDFEOU5weUxnMU1zVjJzUCtTUUdxMmV4dVNucDA0TE1lNGFnblRMaFdSRmdXQkhPWk9vMm5lVW5VMTkvd2Q0ekFlNVRaMXp5cFpyaUU3cHRZQ1duZz09PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+DQogIDxzYW1scDpTdGF0dXM+DQogICAgPHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPg0KICA8L3NhbWxwOlN0YXR1cz4NCiAgPHNhbWw6QXNzZXJ0aW9uIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgSUQ9Il9kNzFhM2E4ZTlmY2M0NWM5ZTlkMjQ4ZWY3MDQ5MzkzZmM4ZjA0ZTVmNzUiIFZlcnNpb249IjIuMCIgSXNzdWVJbnN0YW50PSIyMDE0LTA3LTE3VDAxOjAxOjQ4WiI+DQogICAgPHNhbWw6SXNzdWVyPmh0dHA6Ly9pZHAuZXhhbXBsZS5jb20vbWV0YWRhdGEucGhwPC9zYW1sOklzc3Vlcj4NCiAgICA8c2FtbDpTdWJqZWN0Pg0KICAgICAgPHNhbWw6TmFtZUlEIFNQTmFtZVF1YWxpZmllcj0iaHR0cDovL3NwLmV4YW1wbGUuY29tL2RlbW8xL21ldGFkYXRhLnBocCIgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6bmFtZWlkLWZvcm1hdDp0cmFuc2llbnQiPl9jZTNkMjk0OGI0Y2YyMDE0NmRlZTBhMGIzZGQ2ZjY5YjZjZjg2ZjYyZDc8L3NhbWw6TmFtZUlEPg0KICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpjbTpiZWFyZXIiPg0KICAgICAgICA8c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uRGF0YSBOb3RPbk9yQWZ0ZXI9IjIwMjQtMDEtMThUMDY6MjE6NDhaIiBSZWNpcGllbnQ9Imh0dHA6Ly9zcC5leGFtcGxlLmNvbS9kZW1vMS9pbmRleC5waHA/YWNzIiBJblJlc3BvbnNlVG89Ik9ORUxPR0lOXzRmZWUzYjA0NjM5NWM0ZTc1MTAxMWU5N2Y4OTAwYjUyNzNkNTY2ODUiLz4NCiAgICAgIDwvc2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPg0KICAgIDwvc2FtbDpTdWJqZWN0Pg0KICAgIDxzYW1sOkNvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDE0LTA3LTE3VDAxOjAxOjE4WiIgTm90T25PckFmdGVyPSIyMDI0LTAxLTE4VDA2OjIxOjQ4WiI+DQogICAgICA8c2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPg0KICAgICAgICA8c2FtbDpBdWRpZW5jZT5odHRwOi8vc3AuZXhhbXBsZS5jb20vZGVtbzEvbWV0YWRhdGEucGhwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgPC9zYW1sOkNvbmRpdGlvbnM+DQogICAgPHNhbWw6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDE0LTA3LTE3VDAxOjAxOjQ4WiIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAyNC0wNy0xN1QwOTowMTo0OFoiIFNlc3Npb25JbmRleD0iX2JlOTk2N2FiZDkwNGRkY2FlM2MwZWI0MTg5YWRiZTNmNzFlMzI3Y2Y5MyI+DQogICAgICA8c2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkPC9zYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPg0KICAgICAgPC9zYW1sOkF1dGhuQ29udGV4dD4NCiAgICA8L3NhbWw6QXV0aG5TdGF0ZW1lbnQ+DQogICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9InVpZCIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhzaTp0eXBlPSJ4czpzdHJpbmciPnRlc3Q8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Im1haWwiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4c2k6dHlwZT0ieHM6c3RyaW5nIj50ZXN0QGV4YW1wbGUuY29tPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICAgIDxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJlZHVQZXJzb25BZmZpbGlhdGlvbiIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+DQogICAgICAgIDxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhzaTp0eXBlPSJ4czpzdHJpbmciPnVzZXJzPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4c2k6dHlwZT0ieHM6c3RyaW5nIj5leGFtcGxlcm9sZTE8L3NhbWw6QXR0cmlidXRlVmFsdWU+DQogICAgICA8L3NhbWw6QXR0cmlidXRlPg0KICAgIDwvc2FtbDpBdHRyaWJ1dGVTdGF0ZW1lbnQ+DQogIDwvc2FtbDpBc3NlcnRpb24+DQo8L3NhbWxwOlJlc3BvbnNlPg==

Here I'm bulding 'message' for the SAML validation:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="prepareSAML">
    <DisplayName>AM-prepareSAML</DisplayName>
    <Properties/>
    <Set>
        <Headers>
            <Header name="Content-Type">text/xml; charset=utf-8</Header>
        </Headers>
        <Verb>POST</Verb>
        <Payload contentType="text/xml">{decodeBase64(request.queryparam.saml)}</Payload>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

With my base64 encoded string-SAML(first code block) this function not working.

However, if I will send for example 'less' complex base64 string, e.g "<?xml version="1.0"?>"

PD94bWwgdmVyc2lvbj0iMS4wIj8+

All works, maybe the problem are with the '+' symbol in the load?

Regular base64 decoders work with my SAML.

https://www.base64decode.org/

When I tried to use JS base64 decode solution, I got this output from the script:

<?xml version="1.0"?B[[䙜ܛۜو[쎜؛[H휛\ڜΛ蛙\ΝΔГS싌윛ݛ؛ۈ螛[쎜؛[H휛\ڜΛ蛙\ΝΔГS싌蜜ٜ횛ۈ蒑H왞蘘陌̋XΌMKM͘틌왍MNMMMΙ鎎L舕霜ڛۏH싌蒜ܝYR[의[폈쌌ML
ˌMՌN쌎펖舑\ݚ[蝚[ۏHꝝ닜܋鞘[\K蛛Kٙ[[̋ڛ陞욜ؘ܈蒛䙜ܛٕۜψ㓑SђS獙陌،

쎍X͙M͌LLYNMَL팍̙
M펍HТǶփ䗷7VW#懇GⲶ懂旆׆ƒ涶Ҷ֗FFF熇·6փ䗷7VW ᑌ鍥�ѕɔᡵṌ鑌䉡ё(콝ݜ霌齉켈<$�ᑍ圌荊 <ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/B興Δڙۘ]\铙]و[ۜꝚOHꝝ닝ݝ˝̋뜙ˌ쌌̎Kޛ[ڙȜ옋\ژLH돃B舏Δ陙\雘وT⏈蜙蘙L̋XΌMKM͘틌왍MNMMMΙ鎎L胆G3処綦禗0ᑌ鑉幍齉䁅᝽ɥѡ䴉ᑑ(콝ݜ霌齉켈<$�ᑍ圍幙屽U്坹呕ɔ輼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욙㞙Ռ敜ԕM卛KԑѝҚϏٜΑYٜݕ蛝YC¶G3妖fW&V涐ད̩M坹呥陼豑̩M坹呕ɕY展乩前Maɭ푥19%ՄɽՅ9MH퀕I�荝쉵呡%婄٘�ᨅH夑ͽᭅ]=-虙1Xݐ흍ř鬍孝
ݍ͕輙]Th͡E)ԡٵ顥Yi剝A4᰽퐽<y݅�퍑	5饭퍥I	ʼni艝酕鑉Q塑匴ད̩M坹呕ɕY展临(ᑌ魕她鼸ᑌ頔%呄豑̩`Ԁ单ɑ噥텑乵%%
1鍍i坅ݥ	�9	�᭥圁	DYuE͝
EeYEEݨō镱5흄ŕ
ݍea5፩)	�	�噩5E͝
EeYEE)饑噜a=QɵQ�饥5鉅܁嵑ɵQe嵩%嵩	嵑E፩)	�	eQ险5E͝
EeYEE%)፩15흄ŕ
흍ea5፩)	�	55鹡5%鵄]
MŝM%荑E	EUѝ9
	六	텑ᅍ�ᅥEMa=MݑY݌儕�ѡᨤѸ幕퐝Ņ!!!ؼՌťQ䉨형ʼn٥呙Yᄽ9U镵Uᬝ5Xэ٩Ոሀ퉑卡-͵5D�݅!A4툕$ь썑=`͑A夙)a餁Lᘐԅɉ齑a͹餝푌ͽ轩靝%E	셅ݑ酑	�!Dѕ텕I͝ɍ0͡ѡ!9Y0�ea
aᅈ]!ݥYHi	흙텕I͝ɍ0͡ѡ!9Y0�ea
aᅈ]eYHQ	U݅ݕ�9	�᭥圁	DY=	텅ܕIM-圍홍Ոᑡ՜ݽ\Ὡ	9=ő՝황-1љ兝-Y@ؠʼn允奕푝ᑝYU\͡ݥ͙Q婈ᕱѬ�a腠Ő幁屜ŵ͘ɍ@퍅ĉ塕M退ѱ5䑅�1ᝉ흉!=i=쉹啹TĤ흐ѩ䕑hũ偩ɥ݁ѥ
]霴䰽ጩ`Ԁ单ɑ噥텑伯ds:X509Data></ds:KeyInfoٜΔڙۘ]\逐₃Ƕև巆GW04(్嵱)Mхѕ͍푔ᙅᕔ䉕ɸ齅̩ͥ酵匩ь鍅50舸)͑呕̩MՍ핍̈츴(0퍅局鍑呕̸4(1ͅ尩͍剑彸ᡵṌ額䴉ᑑ(콝ݜ霌齉켈Ľa51M�儵幍х鍔聡屹̩ጴ顑р輽ݝܹ܌齉켈Ľa51M�儈ᥐ䉽܅䍄ᔥ

JS solution used:

https://smarttechie.org/2018/11/16/apigee-how-to-handle-base64-encoding-decoding/

Thanks for all your help,

Solved Solved
0 4 3,460
1 ACCEPTED SOLUTION

deniska
Participant V

OK, found the problem.

It seems that Chrome not encoding \n lines in URL encode, so I needed to decode the incoming request, and then used base64 decode, and all worked.

From other tools(POSTman, SOAPUI), obviously, all works. Only browser URL encoding.

As you can see in my example, new line represented with "+" symbol, however, once Chrome points user to my Proxy, + replaced with " " space, and therefore all fails.

View solution in original post

4 REPLIES 4

deniska
Participant V

deniska
Participant V

OK, found the problem.

It seems that Chrome not encoding \n lines in URL encode, so I needed to decode the incoming request, and then used base64 decode, and all worked.

From other tools(POSTman, SOAPUI), obviously, all works. Only browser URL encoding.

As you can see in my example, new line represented with "+" symbol, however, once Chrome points user to my Proxy, + replaced with " " space, and therefore all fails.

Hi Denis Kalitviansky,

i'm trying to validate the saml assertion but i'm getting below error. i tried

https://community.apigee.com/questions/5851/saml-validation.html but couldn't find any solution.

Please help me with the sample validation policy code and how you are doing?

{
    "fault": {
        "faultstring": "ValidateSAMLAssertion[Validate-SAML-Assertion]: Digital Signature Validation Failed",
        "detail": {
            "errorcode": "steps.saml.validate.SignatureValidationFailed"
        }
    }
}


thank you!

Hi - it seems that yours is a new question.

Please post a new question.