forked from russellhaering/gosaml2
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathbuild_request_test.go
117 lines (94 loc) · 3.42 KB
/
build_request_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package saml2
import (
"bytes"
"compress/flate"
"encoding/base64"
"encoding/xml"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"
"github.com/beevik/etree"
"github.com/stretchr/testify/require"
)
func TestRedirect(t *testing.T) {
r := &http.Request{URL: &url.URL{Path: "/"}}
w := httptest.NewRecorder()
spURL := "https://sp.test"
sp := SAMLServiceProvider{
AssertionConsumerServiceURL: spURL,
AudienceURI: spURL,
IdentityProviderIssuer: spURL,
IdentityProviderSSOURL: "https://idp.test/saml/sso",
SignAuthnRequests: false,
}
require.NoError(t, sp.AuthRedirect(w, r, "foobar"))
require.Len(t, w.HeaderMap, 1, "wrong number of headers was set")
require.Equal(t, http.StatusFound, w.Code, "wrong http status was set")
u, err := url.Parse(w.HeaderMap.Get("Location"))
require.NoError(t, err, "invalid url used for redirect")
require.Equal(t, "idp.test", u.Host)
require.Equal(t, "https", u.Scheme)
require.Equal(t, "foobar", u.Query().Get("RelayState"))
bs, err := base64.StdEncoding.DecodeString(u.Query().Get("SAMLRequest"))
require.NoError(t, err, "error base64 decoding SAMLRequest query param")
fr := flate.NewReader(bytes.NewReader(bs))
req := AuthNRequest{}
require.NoError(t, xml.NewDecoder(fr).Decode(&req), "Error reading/decoding from flate-compressed URL")
iss, err := url.Parse(req.Issuer)
require.NoError(t, err, "error parsing request issuer URL")
require.Equal(t, "sp.test", iss.Host)
require.WithinDuration(t, time.Now(), req.IssueInstant, time.Second, "IssueInstant was not within the expected time frame")
dst, err := url.Parse(req.Destination)
require.NoError(t, err, "error parsing request destination")
require.Equal(t, "https", dst.Scheme)
require.Equal(t, "idp.test", dst.Host)
//Require that the destination is the same as the redirected URL, except params
require.Equal(t, fmt.Sprintf("%s://%s%s", u.Scheme, u.Host, u.Path), dst.String())
}
func TestRequestedAuthnContextOmitted(t *testing.T) {
spURL := "https://sp.test"
sp := SAMLServiceProvider{
AssertionConsumerServiceURL: spURL,
AudienceURI: spURL,
IdentityProviderIssuer: spURL,
IdentityProviderSSOURL: "https://idp.test/saml/sso",
SignAuthnRequests: false,
}
request, err := sp.BuildAuthRequest()
require.NoError(t, err)
doc := etree.NewDocument()
err = doc.ReadFromString(request)
require.NoError(t, err)
el := doc.FindElement("./AuthnRequest/RequestedAuthnContext")
require.Nil(t, el)
}
func TestRequestedAuthnContextIncluded(t *testing.T) {
spURL := "https://sp.test"
sp := SAMLServiceProvider{
AssertionConsumerServiceURL: spURL,
AudienceURI: spURL,
IdentityProviderIssuer: spURL,
IdentityProviderSSOURL: "https://idp.test/saml/sso",
RequestedAuthnContext: &RequestedAuthnContext{
Comparison: AuthnPolicyMatchExact,
Contexts: []string{
AuthnContextPasswordProtectedTransport,
},
},
SignAuthnRequests: false,
}
request, err := sp.BuildAuthRequest()
require.NoError(t, err)
doc := etree.NewDocument()
err = doc.ReadFromString(request)
require.NoError(t, err)
el := doc.FindElement("./AuthnRequest/RequestedAuthnContext")
require.Equal(t, el.SelectAttrValue("Comparison", ""), "exact")
require.Len(t, el.ChildElements(), 1)
el = el.ChildElements()[0]
require.Equal(t, el.Tag, "AuthnContextClassRef")
require.Equal(t, el.Text(), AuthnContextPasswordProtectedTransport)
}