diff --git a/identity_provider_test.go b/identity_provider_test.go index cff0099c..f0a76f1c 100644 --- a/identity_provider_test.go +++ b/identity_provider_test.go @@ -11,10 +11,9 @@ import ( "time" "github.com/crewjam/go-xmlsec" + "github.com/crewjam/saml/testsaml" "github.com/dgrijalva/jwt-go" . "gopkg.in/check.v1" - - "github.com/crewjam/saml/testsaml" ) type IdentityProviderTest struct { @@ -186,13 +185,11 @@ func (test *IdentityProviderTest) TestCanHandleRequestWithNewSession(c *C) { requestURL, err := test.SP.MakeRedirectAuthenticationRequest("ThisIsTheRelayState") c.Assert(err, IsNil) - c.Assert(requestURL.String(), testsaml.EqualsAny, []interface{}{ - // go1.5, go1.6 - "https://idp.example.com/saml/sso?RelayState=ThisIsTheRelayState&SAMLRequest=lJJRixMxEMe%2FypL3bSahV8%2Bwu1CviIVTSq%2F64NuYHb3AJlkzs3r37d1rFQtCqa%2Fhl5n%2F%2F5c060ke056%2BT8RSPcUhcaumklxGDuwSRmIn3j2s3987uwA3lizZ50FVa2YqEnK6y4mnSOWByo%2Fg6eP%2BvlWPIiM7rXlc0BPGcaCFz1EzxsFq9KyqzbwwJHwZ8BcP%2Fb%2B8Zs6q2m5aFfoaACwsYQW3gOCBDBhrlmZlbg0ab8iCtXZpV%2FMF5om2iQWTtMqCuamNrcEcwLibVw5ef1bV7neZNyH1IX273PzLCWL37nDY1XvqQyEvqvpEhY8lZkh1zXFvuUYl%2FhGoqre5RJTL%2BMvJbODrEXWUJMiz6i6KjiTYo2CjT6m65sM8ZLvZ5SH45%2F987mHIP%2B8KoVCrpEykuuvTSsHEYc7c6PMEXaPP%2F1%2F3KwAA%2F%2F8%3D", - // go1.7 - "https://idp.example.com/saml/sso?RelayState=ThisIsTheRelayState&SAMLRequest=lJJRaxQxEMe%2FSsj7Xibhetawu3D2EBeqHNfTB9%2FG7GgDm2TNzGr77aVXxYJwnK%2FhR%2Bb%2F%2F82020Xu84G%2BL8SiHtKUudNLzb4gR%2FYZE7GX4O%2B272%2B9W4Gfa5ESyqTVlpmqxJJvSuYlUb2j%2BiMG%2Bni47fS9yMzeGJ5X9IBpnmgVSjKMaXIGA2u1I5aY8emDv3gc%2F%2BUNc9Fq2HU6jg0AOFjDBq4BIQBZsM6u7cZeW7TBkgPn3NpttBqYFxoyC2bptAN71VjXgD2C9VevPLz%2BrNX%2Bd5k3MY8xfzvf%2FMszxP7d8bhvDjTGSkG0%2BkSVTyXcCnTfnubWS1TiH4FavS01oZzHn17i2Hw9oZ6yRHnU%2FVnRiQRHFGzNc6q%2B%2FYCJht2%2BTDE8%2Fue6p6n8vKmEQp2WupDuL08rFTNHytKalwn61ry8v%2F5XAAAA%2F%2F8%3D", - }) + decodedRequest, err := testsaml.ParseRedirectRequest(requestURL) + c.Assert(err, IsNil) + c.Assert(string(decodedRequest), Equals, "https://sp.example.com/saml2/metadataurn:oasis:names:tc:SAML:2.0:nameid-format:transient") + c.Assert(requestURL.Query().Get("RelayState"), Equals, "ThisIsTheRelayState") r, _ := http.NewRequest("GET", requestURL.String(), nil) test.IDP.ServeSSO(w, r) @@ -214,13 +211,10 @@ func (test *IdentityProviderTest) TestCanHandleRequestWithExistingSession(c *C) w := httptest.NewRecorder() requestURL, err := test.SP.MakeRedirectAuthenticationRequest("ThisIsTheRelayState") c.Assert(err, IsNil) - c.Assert(requestURL.String(), testsaml.EqualsAny, []interface{}{ - // go1.5, go1.6 - "https://idp.example.com/saml/sso?RelayState=ThisIsTheRelayState&SAMLRequest=lJJRixMxEMe%2FypL3bSahV8%2Bwu1CviIVTSq%2F64NuYHb3AJlkzs3r37d1rFQtCqa%2Fhl5n%2F%2F5c060ke056%2BT8RSPcUhcaumklxGDuwSRmIn3j2s3987uwA3lizZ50FVa2YqEnK6y4mnSOWByo%2Fg6eP%2BvlWPIiM7rXlc0BPGcaCFz1EzxsFq9KyqzbwwJHwZ8BcP%2Fb%2B8Zs6q2m5aFfoaACwsYQW3gOCBDBhrlmZlbg0ab8iCtXZpV%2FMF5om2iQWTtMqCuamNrcEcwLibVw5ef1bV7neZNyH1IX273PzLCWL37nDY1XvqQyEvqvpEhY8lZkh1zXFvuUYl%2FhGoqre5RJTL%2BMvJbODrEXWUJMiz6i6KjiTYo2CjT6m65sM8ZLvZ5SH45%2F987mHIP%2B8KoVCrpEykuuvTSsHEYc7c6PMEXaPP%2F1%2F3KwAA%2F%2F8%3D", - // go1.7 - "https://idp.example.com/saml/sso?RelayState=ThisIsTheRelayState&SAMLRequest=lJJRaxQxEMe%2FSsj7Xibhetawu3D2EBeqHNfTB9%2FG7GgDm2TNzGr77aVXxYJwnK%2FhR%2Bb%2F%2F82020Xu84G%2BL8SiHtKUudNLzb4gR%2FYZE7GX4O%2B272%2B9W4Gfa5ESyqTVlpmqxJJvSuYlUb2j%2BiMG%2Bni47fS9yMzeGJ5X9IBpnmgVSjKMaXIGA2u1I5aY8emDv3gc%2F%2BUNc9Fq2HU6jg0AOFjDBq4BIQBZsM6u7cZeW7TBkgPn3NpttBqYFxoyC2bptAN71VjXgD2C9VevPLz%2BrNX%2Bd5k3MY8xfzvf%2FMszxP7d8bhvDjTGSkG0%2BkSVTyXcCnTfnubWS1TiH4FavS01oZzHn17i2Hw9oZ6yRHnU%2FVnRiQRHFGzNc6q%2B%2FYCJht2%2BTDE8%2Fue6p6n8vKmEQp2WupDuL08rFTNHytKalwn61ry8v%2F5XAAAA%2F%2F8%3D", - }) + decodedRequest, err := testsaml.ParseRedirectRequest(requestURL) + c.Assert(err, IsNil) + c.Assert(string(decodedRequest), Equals, "https://sp.example.com/saml2/metadataurn:oasis:names:tc:SAML:2.0:nameid-format:transient") r, _ := http.NewRequest("GET", requestURL.String(), nil) test.IDP.ServeSSO(w, r) diff --git a/samlsp/middleware_test.go b/samlsp/middleware_test.go index b52044c3..28c918a2 100644 --- a/samlsp/middleware_test.go +++ b/samlsp/middleware_test.go @@ -132,13 +132,12 @@ func (test *MiddlewareTest) TestRequireAccountNoCreds(c *C) { "saml_KCosLjAyNDY4Ojw-QEJERkhKTE5QUlRWWFpcXmBiZGZoamxucHJ0dnh6="+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImlkLTAwMDIwNDA2MDgwYTBjMGUxMDEyMTQxNjE4MWExYzFlMjAyMjI0MjYiLCJ1cmkiOiIvZnJvYiJ9.7f-xjK5ZzpP_51YL4aPQSQcIBKKCRb_j6CE9pZieJG0"+ "; Path=/saml2/acs; Max-Age=90") - c.Assert(resp.Header().Get("Location"), testsaml.EqualsAny, []interface{}{ - // go1.5, go1.6 - "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO?RelayState=KCosLjAyNDY4Ojw-QEJERkhKTE5QUlRWWFpcXmBiZGZoamxucHJ0dnh6&SAMLRequest=lJLRb9MwEMb%2Flcjvjc9WGoaVRCqrEJUGVG3hgTfPubUWiV18F2D%2FPU7HxJ7G9nr%2B7r7ffb5mNfEp7PDHhMTF73EI1IopBRMteTLBjkiGndmvPt4YXYI5p8jRxUEUKyJM7GO4joGmEdMe00%2Fv8MvuphUn5jMZKdWyrlVVVWU4pvi99FGSHQctrSNRrLOnD3ae8a%2FD9%2BeS8wOd%2FG0Z03EuyOx65weUM4aWO%2Bx9Qsdyv%2F8sis26Fb5fAICGCmq4AgsOUIHSqlK1ulJWOYUatNaVrnMD0YSbQGwDt0KDWi6UXoA6gDLLNwbefhPF9u%2Ba73zofTg%2Bn8ntg4jMh8Nhu3ikE8VXTHTZLYtE11x800tCto%2FRiuJ9TKPl5%2BVzJSdwd5EaDOz5XnT%2F%2B4IR2faWbSMfwLrmU56zWW%2Fj4N39K29hGOKv64SWsRWcJhTdy4E52UA%2BYzfyKUHXyKfH2f0JAAD%2F%2Fw%3D%3D", - // go1.7 - "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO?RelayState=KCosLjAyNDY4Ojw-QEJERkhKTE5QUlRWWFpcXmBiZGZoamxucHJ0dnh6&SAMLRequest=lJJRb9MwFIX%2FSuT3xNdWGoaVRCqrEJUGVG3hgTfPuWuvSOziewPs36N2TOxpbK9Hx%2FZ3jk%2B7nOUYt%2FhjRpbi9zRG7tSco0ueiV30E7KT4HbLjzfOVuBOOUkKaVTFkhmzUIrXKfI8Yd5h%2FkkBv2xvOnUUObHT2iyaxtR1XcVDTt8rSpr9NFrtA6tihSwU%2FfmOfydoOFWCLHyk2yrlw1nQp5zuaER9xrB6iwNlDKJ3u8%2BqWK86RUMJABZqaOAKPARAA8aa2jTmyngTDFqw1ta2UcWaecZ1ZPFROmXBLEpjSzB7MG7xxsHbb6rY%2FI35juJA8fB8J7cPJnYf9vtN%2BUiniq%2BY%2BZLNVqD69vJufknJ%2FrFaVbxPefLyvP2s0FDeXawOo5Dcq%2F5%2FXzCh%2BMGLb%2FUDWN9%2B8hOuV5s0Urh%2F5RbGMf26zugFOyV5RtW%2FHFiyj0wYpdVPCfpWPx1n%2FycAAP%2F%2F", - }) + redirectURL, err := url.Parse(resp.Header().Get("Location")) + c.Assert(err, IsNil) + decodedRequest, err := testsaml.ParseRedirectRequest(redirectURL) + c.Assert(err, IsNil) + c.Assert(string(decodedRequest), Equals, "https://15661444.ngrok.io/saml2/metadataurn:oasis:names:tc:SAML:2.0:nameid-format:transient") } func (test *MiddlewareTest) TestRequireAccountNoCredsPostBinding(c *C) { @@ -227,13 +226,12 @@ func (test *MiddlewareTest) TestRequireAccountBadCreds(c *C) { "saml_KCosLjAyNDY4Ojw-QEJERkhKTE5QUlRWWFpcXmBiZGZoamxucHJ0dnh6="+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImlkLTAwMDIwNDA2MDgwYTBjMGUxMDEyMTQxNjE4MWExYzFlMjAyMjI0MjYiLCJ1cmkiOiIvZnJvYiJ9.7f-xjK5ZzpP_51YL4aPQSQcIBKKCRb_j6CE9pZieJG0"+ "; Path=/saml2/acs; Max-Age=90") - c.Assert(resp.Header().Get("Location"), testsaml.EqualsAny, []interface{}{ - // go1.5, go1.6 - "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO?RelayState=KCosLjAyNDY4Ojw-QEJERkhKTE5QUlRWWFpcXmBiZGZoamxucHJ0dnh6&SAMLRequest=lJLRb9MwEMb%2Flcjvjc9WGoaVRCqrEJUGVG3hgTfPubUWiV18F2D%2FPU7HxJ7G9nr%2B7r7ffb5mNfEp7PDHhMTF73EI1IopBRMteTLBjkiGndmvPt4YXYI5p8jRxUEUKyJM7GO4joGmEdMe00%2Fv8MvuphUn5jMZKdWyrlVVVWU4pvi99FGSHQctrSNRrLOnD3ae8a%2FD9%2BeS8wOd%2FG0Z03EuyOx65weUM4aWO%2Bx9Qsdyv%2F8sis26Fb5fAICGCmq4AgsOUIHSqlK1ulJWOYUatNaVrnMD0YSbQGwDt0KDWi6UXoA6gDLLNwbefhPF9u%2Ba73zofTg%2Bn8ntg4jMh8Nhu3ikE8VXTHTZLYtE11x800tCto%2FRiuJ9TKPl5%2BVzJSdwd5EaDOz5XnT%2F%2B4IR2faWbSMfwLrmU56zWW%2Fj4N39K29hGOKv64SWsRWcJhTdy4E52UA%2BYzfyKUHXyKfH2f0JAAD%2F%2Fw%3D%3D", + redirectURL, err := url.Parse(resp.Header().Get("Location")) + c.Assert(err, IsNil) + decodedRequest, err := testsaml.ParseRedirectRequest(redirectURL) + c.Assert(err, IsNil) + c.Assert(string(decodedRequest), Equals, "https://15661444.ngrok.io/saml2/metadataurn:oasis:names:tc:SAML:2.0:nameid-format:transient") - // go1.7 - "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO?RelayState=KCosLjAyNDY4Ojw-QEJERkhKTE5QUlRWWFpcXmBiZGZoamxucHJ0dnh6&SAMLRequest=lJJRb9MwFIX%2FSuT3xNdWGoaVRCqrEJUGVG3hgTfPuWuvSOziewPs36N2TOxpbK9Hx%2FZ3jk%2B7nOUYt%2FhjRpbi9zRG7tSco0ueiV30E7KT4HbLjzfOVuBOOUkKaVTFkhmzUIrXKfI8Yd5h%2FkkBv2xvOnUUObHT2iyaxtR1XcVDTt8rSpr9NFrtA6tihSwU%2FfmOfydoOFWCLHyk2yrlw1nQp5zuaER9xrB6iwNlDKJ3u8%2BqWK86RUMJABZqaOAKPARAA8aa2jTmyngTDFqw1ta2UcWaecZ1ZPFROmXBLEpjSzB7MG7xxsHbb6rY%2FI35juJA8fB8J7cPJnYf9vtN%2BUiniq%2BY%2BZLNVqD69vJufknJ%2FrFaVbxPefLyvP2s0FDeXawOo5Dcq%2F5%2FXzCh%2BMGLb%2FUDWN9%2B8hOuV5s0Urh%2F5RbGMf26zugFOyV5RtW%2FHFiyj0wYpdVPCfpWPx1n%2FycAAP%2F%2F", - }) } func (test *MiddlewareTest) TestRequireAccountExpiredCreds(c *C) { @@ -260,13 +258,11 @@ func (test *MiddlewareTest) TestRequireAccountExpiredCreds(c *C) { "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImlkLTAwMDIwNDA2MDgwYTBjMGUxMDEyMTQxNjE4MWExYzFlMjAyMjI0MjYiLCJ1cmkiOiIvZnJvYiJ9.7f-xjK5ZzpP_51YL4aPQSQcIBKKCRb_j6CE9pZieJG0"+ "; Path=/saml2/acs; Max-Age=90") - c.Assert(resp.Header().Get("Location"), testsaml.EqualsAny, []interface{}{ - // go1.5, go1.6 - "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO?RelayState=KCosLjAyNDY4Ojw-QEJERkhKTE5QUlRWWFpcXmBiZGZoamxucHJ0dnh6&SAMLRequest=lJLRb9MwEMb%2Flcjvjc9WGoaVRCqrEJUGVG3hgTfPubUWiV18F2D%2FPU7HxJ7G9nr%2B7r7ffb5mNfEp7PDHhMTF73EI1IopBRMteTLBjkiGndmvPt4YXYI5p8jRxUEUKyJM7GO4joGmEdMe00%2Fv8MvuphUn5jMZKdWyrlVVVWU4pvi99FGSHQctrSNRrLOnD3ae8a%2FD9%2BeS8wOd%2FG0Z03EuyOx65weUM4aWO%2Bx9Qsdyv%2F8sis26Fb5fAICGCmq4AgsOUIHSqlK1ulJWOYUatNaVrnMD0YSbQGwDt0KDWi6UXoA6gDLLNwbefhPF9u%2Ba73zofTg%2Bn8ntg4jMh8Nhu3ikE8VXTHTZLYtE11x800tCto%2FRiuJ9TKPl5%2BVzJSdwd5EaDOz5XnT%2F%2B4IR2faWbSMfwLrmU56zWW%2Fj4N39K29hGOKv64SWsRWcJhTdy4E52UA%2BYzfyKUHXyKfH2f0JAAD%2F%2Fw%3D%3D", - - // go1.7 - "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO?RelayState=KCosLjAyNDY4Ojw-QEJERkhKTE5QUlRWWFpcXmBiZGZoamxucHJ0dnh6&SAMLRequest=lJJRb9MwFIX%2FSuT3xNdWGoaVRCqrEJUGVG3hgTfPuWuvSOziewPs36N2TOxpbK9Hx%2FZ3jk%2B7nOUYt%2FhjRpbi9zRG7tSco0ueiV30E7KT4HbLjzfOVuBOOUkKaVTFkhmzUIrXKfI8Yd5h%2FkkBv2xvOnUUObHT2iyaxtR1XcVDTt8rSpr9NFrtA6tihSwU%2FfmOfydoOFWCLHyk2yrlw1nQp5zuaER9xrB6iwNlDKJ3u8%2BqWK86RUMJABZqaOAKPARAA8aa2jTmyngTDFqw1ta2UcWaecZ1ZPFROmXBLEpjSzB7MG7xxsHbb6rY%2FI35juJA8fB8J7cPJnYf9vtN%2BUiniq%2BY%2BZLNVqD69vJufknJ%2FrFaVbxPefLyvP2s0FDeXawOo5Dcq%2F5%2FXzCh%2BMGLb%2FUDWN9%2B8hOuV5s0Urh%2F5RbGMf26zugFOyV5RtW%2FHFiyj0wYpdVPCfpWPx1n%2FycAAP%2F%2F", - }) + redirectURL, err := url.Parse(resp.Header().Get("Location")) + c.Assert(err, IsNil) + decodedRequest, err := testsaml.ParseRedirectRequest(redirectURL) + c.Assert(err, IsNil) + c.Assert(string(decodedRequest), Equals, "https://15661444.ngrok.io/saml2/metadataurn:oasis:names:tc:SAML:2.0:nameid-format:transient") } func (test *MiddlewareTest) TestRequireAccountPanicOnRequestToACS(c *C) { diff --git a/service_provider_test.go b/service_provider_test.go index e3f184eb..4caa9998 100644 --- a/service_provider_test.go +++ b/service_provider_test.go @@ -8,9 +8,9 @@ import ( "testing" "time" - . "gopkg.in/check.v1" - "github.com/crewjam/saml/testsaml" + + . "gopkg.in/check.v1" ) // Hook up gocheck into the "go test" runner. @@ -117,12 +117,11 @@ func (test *ServiceProviderTest) TestCanProduceRedirectRequest(c *C) { redirectURL, err := s.MakeRedirectAuthenticationRequest("relayState") c.Assert(err, IsNil) - c.Assert(redirectURL.String(), testsaml.EqualsAny, []interface{}{ - // go1.5, go1.6 - "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO?RelayState=relayState&SAMLRequest=lJLRb9MwEMb%2FlcjvjX0miyYriVRWISoNqJrCA2%2Bec2stErv4LsD%2Be5yOiT2N8Xr%2B7r7ffb5mPfMp7PH7jMTFr2kM1Io5BRMteTLBTkiGnenXH26NLpU5p8jRxVEUayJM7GO4iYHmCVOP6Yd3%2BHl%2F24oT85mMlHBV11BVVRmOKX4rfZRkp1FL60gUm%2Bzpg11m%2FO3ww7nk%2FEAnf1fGdFwKMrve%2BxHlgqHlHgef0LHs%2B0%2Bi2G5a4YeVUkqrStXqWlnlFIICDRXUcA0WHKBWWutK17mBaMZtILaBW6EVXK1ArxQcFJg3YDR8FcXuz5pvfRh8OL6cyd2jiMz7w2G3eqITxRdMdNkti0TXXHzTa0K2T9GK4l1Mk%2BWX5UslJ3B%2FkRoM7PlBdP%2F6ggnZDpZtIx%2FBuuZjnrPd7OLo3cN%2F3sI4xp83CS1jKzjNKLrXA3OygXzGbuRzgq6Rz4%2Bz%2Bx0AAP%2F%2F", - // go1.7 - "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO?RelayState=relayState&SAMLRequest=lJJfb9MwFMW%2FSuT3xH%2FIoslKIpVViEoDqrbwwNudc9dekdjF9wbYt0fpmNjTGK9Hx%2FbvHJ92Ncsp7vD7jCzFr2mM3Kk5R5%2BAiX2ECdlL8PvVh1vvKuPPOUkKaVTFihmzUIo3KfI8Yd5j%2FkEBP%2B9uO3USObPX2l41ja3ruorHnL5VlDTDNDoNgVWxRhaKsNzx9wQN50qQhU90V6V8XAR9zumeRtQLhtM7HChjEL3ff1LFZt0pGkpjjDO1acy1ARMMWmOdrW1jry3YYNEZ51ztGlVsmGfcRBaI0iln7FVpXWnswVj%2Fxnpnv6pi%2ByfmW4oDxePLndw9mti%2FPxy25ROdKr5g5ks2VxnVt5d382tKhqdqVfEu5QnkZfui0FDeX6weo5A8qP5fXzChwAACrX4E69uPMOFmvU0jhYf%2F3MI4pp83GUGwU5JnVP3rgSVDZMIorX5O0Lf6%2BTj73wEAAP%2F%2F", - }) + decodedRequest, err := testsaml.ParseRedirectRequest(redirectURL) + c.Assert(err, IsNil) + c.Assert(redirectURL.Host, Equals, "idp.testshib.org") + c.Assert(redirectURL.Path, Equals, "/idp/profile/SAML2/Redirect/SSO") + c.Assert(string(decodedRequest), Equals, "https://15661444.ngrok.io/saml2/metadataurn:oasis:names:tc:SAML:2.0:nameid-format:transient") } func (test *ServiceProviderTest) TestCanProducePostRequest(c *C) { diff --git a/testsaml/parse.go b/testsaml/parse.go new file mode 100644 index 00000000..70dbd601 --- /dev/null +++ b/testsaml/parse.go @@ -0,0 +1,23 @@ +package testsaml + +import ( + "bytes" + "compress/flate" + "encoding/base64" + "fmt" + "io/ioutil" + "net/url" +) + +// ParseRedirectRequest returns the decoded SAML AuthnRequest from an HTTP-Redirect URL +func ParseRedirectRequest(u *url.URL) ([]byte, error) { + compressedRequest, err := base64.StdEncoding.DecodeString(u.Query().Get("SAMLRequest")) + if err != nil { + return nil, fmt.Errorf("cannot decode request: %s", err) + } + buf, err := ioutil.ReadAll(flate.NewReader(bytes.NewReader(compressedRequest))) + if err != nil { + return nil, fmt.Errorf("cannot decompress request: %s", err) + } + return buf, nil +}