diff --git a/connector/saml/saml_test.go b/connector/saml/saml_test.go
index cba0fe12..bb7fa1b2 100644
--- a/connector/saml/saml_test.go
+++ b/connector/saml/saml_test.go
@@ -6,24 +6,216 @@ import (
"encoding/pem"
"errors"
"io/ioutil"
+ "sort"
"strings"
"testing"
"time"
"github.com/Sirupsen/logrus"
-
+ "github.com/kylelemons/godebug/pretty"
dsig "github.com/russellhaering/goxmldsig"
"github.com/coreos/dex/connector"
)
-const (
- defaultIssuer = "http://www.okta.com/exk91cb99lKkKSYoy0h7"
- defaultRedirectURI = "http://localhost:5556/dex/callback"
+// responseTest maps a SAML 2.0 response object to a set of expected values.
+//
+// Tests are defined in the "testdata" directory and are self-signed using xmlsec1.
+//
+// To add a new test, define a new, unsigned SAML 2.0 response that exercises some
+// case, then sign it using the "testdata/gen.sh" script.
+//
+// cp testdata/good-resp.tmpl testdata/( testname ).tmpl
+// vim ( testname ).tmpl # Modify your template for your test case.
+// vim testdata/gen.sh # Add a xmlsec1 command to the generation script.
+// ./testdata/gen.sh # Sign your template.
+//
+// To install xmlsec1 on Fedora run:
+//
+// sudo dnf install xmlsec1 xmlsec1-openssl
+//
+// On mac:
+//
+// brew install Libxmlsec1
+//
+type responseTest struct {
+ // CA file and XML file of the response.
+ caFile string
+ respFile string
- // Response ID embedded in our testdata.
- testDataResponseID = "_fd1b3ef9-ec09-44a7-a66b-0d39c250f6a0"
-)
+ // Values that should be used to validate the signature.
+ now string
+ inResponseTo string
+ redirectURI string
+
+ // Attribute customization.
+ usernameAttr string
+ emailAttr string
+ groupsAttr string
+
+ // Expected outcome of the test.
+ wantErr bool
+ wantIdent connector.Identity
+}
+
+func TestGoodResponse(t *testing.T) {
+ test := responseTest{
+ caFile: "testdata/ca.crt",
+ respFile: "testdata/good-resp.xml",
+ now: "2017-04-04T04:34:59.330Z",
+ usernameAttr: "Name",
+ emailAttr: "email",
+ inResponseTo: "6zmm5mguyebwvajyf2sdwwcw6m",
+ redirectURI: "http://127.0.0.1:5556/dex/callback",
+ wantIdent: connector.Identity{
+ UserID: "eric.chiang+okta@coreos.com",
+ Username: "Eric",
+ Email: "eric.chiang+okta@coreos.com",
+ EmailVerified: true,
+ },
+ }
+ test.run(t)
+}
+
+func TestGroups(t *testing.T) {
+ test := responseTest{
+ caFile: "testdata/ca.crt",
+ respFile: "testdata/good-resp.xml",
+ now: "2017-04-04T04:34:59.330Z",
+ usernameAttr: "Name",
+ emailAttr: "email",
+ groupsAttr: "groups",
+ inResponseTo: "6zmm5mguyebwvajyf2sdwwcw6m",
+ redirectURI: "http://127.0.0.1:5556/dex/callback",
+ wantIdent: connector.Identity{
+ UserID: "eric.chiang+okta@coreos.com",
+ Username: "Eric",
+ Email: "eric.chiang+okta@coreos.com",
+ EmailVerified: true,
+ Groups: []string{"Admins", "Everyone"},
+ },
+ }
+ test.run(t)
+}
+
+// TestOkta tests against an actual response from Okta.
+func TestOkta(t *testing.T) {
+ test := responseTest{
+ caFile: "testdata/okta-ca.pem",
+ respFile: "testdata/okta-resp.xml",
+ now: "2017-04-04T04:34:59.330Z",
+ usernameAttr: "Name",
+ emailAttr: "email",
+ inResponseTo: "6zmm5mguyebwvajyf2sdwwcw6m",
+ redirectURI: "http://127.0.0.1:5556/dex/callback",
+ wantIdent: connector.Identity{
+ UserID: "eric.chiang+okta@coreos.com",
+ Username: "Eric",
+ Email: "eric.chiang+okta@coreos.com",
+ EmailVerified: true,
+ },
+ }
+ test.run(t)
+}
+
+func TestBadStatus(t *testing.T) {
+ test := responseTest{
+ caFile: "testdata/ca.crt",
+ respFile: "testdata/bad-status.xml",
+ now: "2017-04-04T04:34:59.330Z",
+ usernameAttr: "Name",
+ emailAttr: "email",
+ inResponseTo: "6zmm5mguyebwvajyf2sdwwcw6m",
+ redirectURI: "http://127.0.0.1:5556/dex/callback",
+ wantErr: true,
+ }
+ test.run(t)
+}
+
+func TestInvalidCA(t *testing.T) {
+ test := responseTest{
+ caFile: "testdata/bad-ca.crt", // Not the CA that signed this response.
+ respFile: "testdata/good-resp.xml",
+ now: "2017-04-04T04:34:59.330Z",
+ usernameAttr: "Name",
+ emailAttr: "email",
+ inResponseTo: "6zmm5mguyebwvajyf2sdwwcw6m",
+ redirectURI: "http://127.0.0.1:5556/dex/callback",
+ wantErr: true,
+ }
+ test.run(t)
+}
+
+func TestUnsignedResponse(t *testing.T) {
+ test := responseTest{
+ caFile: "testdata/ca.crt",
+ respFile: "testdata/good-resp.tmpl", // Use the unsigned template, not the signed document.
+ now: "2017-04-04T04:34:59.330Z",
+ usernameAttr: "Name",
+ emailAttr: "email",
+ inResponseTo: "6zmm5mguyebwvajyf2sdwwcw6m",
+ redirectURI: "http://127.0.0.1:5556/dex/callback",
+ wantErr: true,
+ }
+ test.run(t)
+}
+
+func TestExpiredAssertion(t *testing.T) {
+ test := responseTest{
+ caFile: "testdata/ca.crt",
+ respFile: "testdata/assertion-signed.xml",
+ now: "2020-04-04T04:34:59.330Z", // Assertion has expired.
+ usernameAttr: "Name",
+ emailAttr: "email",
+ inResponseTo: "6zmm5mguyebwvajyf2sdwwcw6m",
+ redirectURI: "http://127.0.0.1:5556/dex/callback",
+ wantErr: true,
+ }
+ test.run(t)
+}
+
+// TestAssertionSignedNotResponse ensures the connector validates SAML 2.0
+// responses where the assertion is signed but the root element, the
+// response, isn't.
+func TestAssertionSignedNotResponse(t *testing.T) {
+ test := responseTest{
+ caFile: "testdata/ca.crt",
+ respFile: "testdata/assertion-signed.xml",
+ now: "2017-04-04T04:34:59.330Z",
+ usernameAttr: "Name",
+ emailAttr: "email",
+ inResponseTo: "6zmm5mguyebwvajyf2sdwwcw6m",
+ redirectURI: "http://127.0.0.1:5556/dex/callback",
+ wantIdent: connector.Identity{
+ UserID: "eric.chiang+okta@coreos.com",
+ Username: "Eric",
+ Email: "eric.chiang+okta@coreos.com",
+ EmailVerified: true,
+ },
+ }
+ test.run(t)
+}
+
+// TestTwoAssertionFirstSigned tries to catch an edge case where an attacker
+// provides a second assertion that's not signed.
+func TestTwoAssertionFirstSigned(t *testing.T) {
+ test := responseTest{
+ caFile: "testdata/ca.crt",
+ respFile: "testdata/two-assertions-first-signed.xml",
+ now: "2017-04-04T04:34:59.330Z",
+ usernameAttr: "Name",
+ emailAttr: "email",
+ inResponseTo: "6zmm5mguyebwvajyf2sdwwcw6m",
+ redirectURI: "http://127.0.0.1:5556/dex/callback",
+ wantIdent: connector.Identity{
+ UserID: "eric.chiang+okta@coreos.com",
+ Username: "Eric",
+ Email: "eric.chiang+okta@coreos.com",
+ EmailVerified: true,
+ },
+ }
+ test.run(t)
+}
func loadCert(ca string) (*x509.Certificate, error) {
data, err := ioutil.ReadFile(ca)
@@ -37,6 +229,63 @@ func loadCert(ca string) (*x509.Certificate, error) {
return x509.ParseCertificate(block.Bytes)
}
+func (r responseTest) run(t *testing.T) {
+ c := Config{
+ CA: r.caFile,
+ UsernameAttr: r.usernameAttr,
+ EmailAttr: r.emailAttr,
+ GroupsAttr: r.groupsAttr,
+ RedirectURI: r.redirectURI,
+ // Never logging in, don't need this.
+ SSOURL: "http://foo.bar/",
+ }
+ now, err := time.Parse(timeFormat, r.now)
+ if err != nil {
+ t.Fatalf("parse test time: %v", err)
+ }
+
+ conn, err := c.openConnector(logrus.New())
+ if err != nil {
+ t.Fatal(err)
+ }
+ conn.now = func() time.Time { return now }
+ resp, err := ioutil.ReadFile(r.respFile)
+ if err != nil {
+ t.Fatal(err)
+ }
+ samlResp := base64.StdEncoding.EncodeToString(resp)
+
+ scopes := connector.Scopes{
+ OfflineAccess: false,
+ Groups: true,
+ }
+ ident, err := conn.HandlePOST(scopes, samlResp, r.inResponseTo)
+ if err != nil {
+ if !r.wantErr {
+ t.Fatalf("handle response: %v", err)
+ }
+ return
+ }
+
+ if r.wantErr {
+ t.Fatalf("wanted error")
+ }
+ sort.Strings(ident.Groups)
+ sort.Strings(r.wantIdent.Groups)
+ if diff := pretty.Compare(ident, r.wantIdent); diff != "" {
+ t.Error(diff)
+ }
+}
+
+const (
+ defaultIssuer = "http://www.okta.com/exk91cb99lKkKSYoy0h7"
+ defaultRedirectURI = "http://localhost:5556/dex/callback"
+
+ // Response ID embedded in our testdata.
+ testDataResponseID = "_fd1b3ef9-ec09-44a7-a66b-0d39c250f6a0"
+)
+
+// Depricated: Use testing framework established above.
func runVerify(t *testing.T, ca string, resp string, shouldSucceed bool) {
cert, err := loadCert(ca)
if err != nil {
@@ -51,7 +300,7 @@ func runVerify(t *testing.T, ca string, resp string, shouldSucceed bool) {
t.Fatal(err)
}
- if _, err := verify(validator, data); err != nil {
+ if _, _, err := verifyResponseSig(validator, data); err != nil {
if shouldSucceed {
t.Fatal(err)
}
@@ -62,6 +311,7 @@ func runVerify(t *testing.T, ca string, resp string, shouldSucceed bool) {
}
}
+// Depricated: Use testing framework established above.
func newProvider(issuer string, redirectURI string) *provider {
if issuer == "" {
issuer = defaultIssuer
@@ -106,28 +356,6 @@ func TestVerifyUnsignedMessageAndUnsignedAssertion(t *testing.T) {
runVerify(t, "testdata/idp-cert.pem", "testdata/idp-resp.xml", false)
}
-func TestHandlePOST(t *testing.T) {
- p := newProvider("", "")
- scopes := connector.Scopes{
- OfflineAccess: false,
- Groups: true,
- }
- data, err := ioutil.ReadFile("testdata/idp-resp.xml")
- if err != nil {
- t.Fatal(err)
- }
- ident, err := p.HandlePOST(scopes, base64.StdEncoding.EncodeToString(data), testDataResponseID)
- if err != nil {
- t.Fatal(err)
- }
- if ident.UserID != "eric.chiang+okta@coreos.com" {
- t.Fatalf("unexpected UserID %q", ident.UserID)
- }
- if ident.Username != "admin" {
- t.Fatalf("unexpected Username: %q", ident.UserID)
- }
-}
-
func TestValidateStatus(t *testing.T) {
p := newProvider("", "")
var err error
diff --git a/connector/saml/testdata/assertion-signed.tmpl b/connector/saml/testdata/assertion-signed.tmpl
new file mode 100644
index 00000000..239bf271
--- /dev/null
+++ b/connector/saml/testdata/assertion-signed.tmpl
@@ -0,0 +1,56 @@
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+ Eric
+
+
+ Everyone
+ Admins
+
+
+
+
diff --git a/connector/saml/testdata/assertion-signed.xml b/connector/saml/testdata/assertion-signed.xml
new file mode 100644
index 00000000..308676d4
--- /dev/null
+++ b/connector/saml/testdata/assertion-signed.xml
@@ -0,0 +1,79 @@
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ kDdpmKMPp7zjUeMTuntXJFpT6cs=
+
+
+ Q12w9zPo9Bqn3W2OT7lbFbhfIDQrp7SXd/+9ZWpY4mv3ApgaOcNX2VtpSE0EjorU
+1NyrktVOkCYueJm/HVQF7gyF85KRlPBDLBZOwxbnnmrRFoCk+U2kjIt8k8eZ7NsD
+jLFGFgEveS359uvaHZR1Exbr0PBYwS7aXR3fpmjMjZ9T8f8Oe3Nt/9nWPgz/dFhb
+Aa+AniWuupfq2v6YMLZ+9GLiO0sOr8UVkW8AYOm2Bin30epikXT1Axi/VxWz/fjP
+nMUkgusFnhkgmIf/YncAv4S9GY6DcaV2iEj6cL70S7pcgaeRFi3iozigl+9a+lFo
+dt3Jy8Jq/N3OAyDP2DxLEw==
+
+
+MIIDGTCCAgGgAwIBAgIJAKLbLcQajEf8MA0GCSqGSIb3DQEBCwUAMCMxDDAKBgNV
+BAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNvbTAeFw0xNzA0MDQwNzAwNTNaFw0z
+NzAzMzAwNzAwNTNaMCMxDDAKBgNVBAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNv
+bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKH3dKWbRqCIZD2m3aHI
+4lfBT+u/4DECde74Ggq9WugdTucVQzDZUTaI7wzn17JM9hdPmXvaSRG9BaB1H3uO
+ZCs/fmdhBERRhPvuEVfAZaFfQfR7vn7WvUzT7zwMLLB8+EHzL3fOSGM2QnCOMeUD
+AB27Pb0fuBW43NXaTD9rwfFCHvo1UP+TBJIPnV65HMeMGIrtGLt7MZTPuPm3LnYA
+faXLf2vWSzL5nAgnJvUgceZXmyuciBfXpt8c1jIsj4y3tBoRTRqaxuaW1Eo7WMKF
+a7s6KvTBKErPKuzAoIcVB4ir6jm1ticAgB72SScKtPJJdEPemTXRNNzkiw7VbpY9
+QacCAwEAAaNQME4wHQYDVR0OBBYEFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MB8GA1Ud
+IwQYMBaAFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAHVXB5QmZfki9QpKzoiBNfpQ/mo6XWhExLGBTJXEWJT3P7JP
+oR4Z0+85bp0fUK338s+WjyqTn0U55Jtp0B65Qxy6ythkZat/6NPp/S7gto2De6pS
+hSGygokQioVQnoYQeK0MXl2QbtrWwNiM4HC+9yohbUfjwv8yI7opwn/rjB6X/4De
+oX2YzwTBJgoIXF7zMKYFF0DrKQjbTQr/a7kfNjq4930o7VhFph9Qpdv0EWM3svTd
+esSffLKbWcabtyMtCr5QyEwZiozd567oWFWZYeHQyEtd+w6tAFmz9ZslipdQEa/j
+1xUtrScuXt19sUfOgjUvA+VUNeMLDdpHUKHNW/Q=
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+ Eric
+
+
+ Everyone
+ Admins
+
+
+
+
diff --git a/connector/saml/testdata/bad-ca.crt b/connector/saml/testdata/bad-ca.crt
new file mode 100644
index 00000000..e7843494
--- /dev/null
+++ b/connector/saml/testdata/bad-ca.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDGTCCAgGgAwIBAgIJAINei+KBx541MA0GCSqGSIb3DQEBCwUAMCMxDDAKBgNV
+BAoMA0JBRDETMBEGA1UEAwwKY29yZW9zLmNvbTAeFw0xNzA0MDQwNzAwNTNaFw0z
+NzAzMzAwNzAwNTNaMCMxDDAKBgNVBAoMA0JBRDETMBEGA1UEAwwKY29yZW9zLmNv
+bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKfSVQCQMJhwdeesQqZo
+YHktgGjKA//p176kWoqVEX8+cVgKc1IEAzN73L0KsBcNkaItbZycQxkku8NGUYvt
+inEK8V61vjK3IQBOV2+qKOeWvHPXd280I2JSGy768ELpZcaEmnA0CVbMaLdHLFQ/
+tcRocDcMKDhNexlsJ/cDPwzSkky6FU6UnaSih+I432UeJs/hRvAs1YJ3+G6uSVQ7
+xo2Fk2i+qd3IvRWOBagwEhEFcd/MfAu4+w+UYW4W1BC9zJoO2ETBgUVJzaiUGZ5z
+rX/KNAX/+kAQWQLKW1sVgRKOI2yfyIVaUzF6V2uxwHrbeV75Pr3ClVdvuUWRcXKH
+Wn8CAwEAAaNQME4wHQYDVR0OBBYEFLw+L3SLMIR2wfd7IQG1m3rlgGP7MB8GA1Ud
+IwQYMBaAFLw+L3SLMIR2wfd7IQG1m3rlgGP7MAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBABH2mDQuf+JqjHtBCp9coi1WuX5xJuoSKyOAvlz7QJk0bb+W
+oONg+ETQ7jT7KheiFQorghdulZerv+L1dmLU5ut/Zbf1zoaWLslOgVPpOy6LP0aS
+uaa31jm7Qpig47+kTZEpPN6vUPpmAD70/uo3NgRNj8pztkWr08fEIbX/3ukHvFUE
+XPxYxgF5tFj8EY6cdflzlC/0TYmJiHt/viv/yQfrvMBRvsVHfjfzNRxbNwfEdKuf
+YIs5KeP2al7APsmF5d/UFGzoQGXaKEOpCRJ+Oj3spooLhhzWqV4gPZLVgU0DD6ja
+GPb2XgLA9mdEmMukHU0RMeb8R+r8RvytWKvuJQE=
+-----END CERTIFICATE-----
diff --git a/connector/saml/testdata/bad-ca.key b/connector/saml/testdata/bad-ca.key
new file mode 100644
index 00000000..e8282053
--- /dev/null
+++ b/connector/saml/testdata/bad-ca.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCn0lUAkDCYcHXn
+rEKmaGB5LYBoygP/6de+pFqKlRF/PnFYCnNSBAMze9y9CrAXDZGiLW2cnEMZJLvD
+RlGL7YpxCvFetb4ytyEATldvqijnlrxz13dvNCNiUhsu+vBC6WXGhJpwNAlWzGi3
+RyxUP7XEaHA3DCg4TXsZbCf3Az8M0pJMuhVOlJ2koofiON9lHibP4UbwLNWCd/hu
+rklUO8aNhZNovqndyL0VjgWoMBIRBXHfzHwLuPsPlGFuFtQQvcyaDthEwYFFSc2o
+lBmec61/yjQF//pAEFkCyltbFYESjiNsn8iFWlMxeldrscB623le+T69wpVXb7lF
+kXFyh1p/AgMBAAECggEAHh/PSk6XqoVlZLSzMhPCXX4hcq3wkdtz8rCl4AJqJaEb
+z2Xw1WQK/w7YzMZCXaD951KoPlh+YuEJI0BYGvoEw83nDc0p2wisT9XANDcjKI8S
+POkMc1W0lE2Qu5onzpr+vefHoSR2GLKQiXWpK2ZURnFI01jHT3P5CNM1SU2336ES
+XT1GXlxTz59BS04bySS3s8PQZTtmFvQAjtjOWkg+nzTYgEO7xU5968Px+jdlO+xf
+ZKtjlRKRNRmVlylUvCmIT6kIzIdyjuBqw4yx0bM1Av9QwpPuDkRWBeiT8o5xeY+L
+yOSxUCg24CGgAl6mGVXWh+BC9Z3h8dXg9eMervT9gQKBgQDS6QffOBr+j19FiQwH
+t+5h2klOR/mu8TX6oW8Dc6o5YsnLt0uQqa2jLq8kYRkOBVg68mMFvZXmhPoKv4hk
+rOfDKjVfPz9ShrvuY301BAp/hdi/hNP+MAt683UlcnpwLOaASZMr+MjdnVVzfF6X
+iNlV2RE3pAxSFkVlMPJJTmPPEQKBgQDLsxbYFj4JBKhMehdcsqjUtDuzLBPqisVa
+cWKACxPAXIjztsEXF4F7sQk7q68uzLU80uPBVAJjf6lWwK9tcUdcBFHCXdqj8ZXB
+77W4gZSkqHY0T6DJF+NZRF+z4cOg3qtDjTvqhetl5yyiY9IPyiSckNAz40pWD/0X
+U/0nObuwjwKBgQCpWpUHmHWUkmtd2n3edMLlr/HM+d5zqxw89APAMdAt5DVFbxku
+QBE9Ru87tvv3VjNSoe8BXQpQ39Yna0SKEozHGc1hfdfK3IVrFlgjieskGsXAg1f2
+c33EbFlUiGfoSyWLPYj/dfVUflFvOh56b1iUpog8tW1vPJLcfkEOu/NJAQKBgQCu
+LAp7Z8FRarcQ9VAmhekQPq/RSv4YjOGkrNChVVdlInpDkV9XBFVF0yFm8SzQYl8R
+i+0McG2+b/j2YbleZf6zMkpKXH/HsJjxg6qpAbt8c0LnBbMgXxmZSXpfT8o7MknU
+b93scOfPcTRcAegqchiN+tDbnRwBrJgmqz0JnjbbBwKBgCXOWMgS8Azvvw+lUqua
+yLdcAilAaqchgVBkI5ATZQodopEP+Gvevvzh6G8uQJp9fGrL/fR/tNg2viwCF/X8
+ROATx1z98/ItA3kyYhiNt/A6EqOb8SVOMq/eeMpvk+RB6gA9YdMf5H9XClW4vxLy
+jaw+YQ6hOyMTmFfUI2/FumFE
+-----END PRIVATE KEY-----
diff --git a/connector/saml/testdata/bad-status.tmpl b/connector/saml/testdata/bad-status.tmpl
new file mode 100644
index 00000000..093ae948
--- /dev/null
+++ b/connector/saml/testdata/bad-status.tmpl
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+ Eric
+
+
+ Everyone
+ Admins
+
+
+
+
diff --git a/connector/saml/testdata/bad-status.xml b/connector/saml/testdata/bad-status.xml
new file mode 100644
index 00000000..7de16ed5
--- /dev/null
+++ b/connector/saml/testdata/bad-status.xml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 96Mymeqjk6Mm0azcGKf6nD6SFWY=
+
+
+ AbzrvvisCPqcZ0OnkYNaFeuC8wIkivlIL479c3HJmFJycXLxm6LzS7wILw47huzP
+/8r2FnZ3MT/qJdibz53zNFXBADu2af/lSx9bkuxZpYN5J91cgCjUt68xF8Xvo4d8
+jqOKq3H3C7DqU52QyF+XoPKHaBWUcefJoeLQEwUm9C+U6mSP5AZ82m1DoqyhOuWk
+UYTjVUjVro+J1x9Bp/dyZ8OczaN+S9vIYm6AbsV5klYPQug951da5KJ/K8fvure9
+OIHaLnEb4BtQb7qDA8+3jPU7c88XvP+27FtSqiWM0vGGSc9pq4kS5hHmsrdbIkyl
+Ajr+mNXxlNnXRQNEsqE+Gw==
+
+
+MIIDGTCCAgGgAwIBAgIJAKLbLcQajEf8MA0GCSqGSIb3DQEBCwUAMCMxDDAKBgNV
+BAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNvbTAeFw0xNzA0MDQwNzAwNTNaFw0z
+NzAzMzAwNzAwNTNaMCMxDDAKBgNVBAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNv
+bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKH3dKWbRqCIZD2m3aHI
+4lfBT+u/4DECde74Ggq9WugdTucVQzDZUTaI7wzn17JM9hdPmXvaSRG9BaB1H3uO
+ZCs/fmdhBERRhPvuEVfAZaFfQfR7vn7WvUzT7zwMLLB8+EHzL3fOSGM2QnCOMeUD
+AB27Pb0fuBW43NXaTD9rwfFCHvo1UP+TBJIPnV65HMeMGIrtGLt7MZTPuPm3LnYA
+faXLf2vWSzL5nAgnJvUgceZXmyuciBfXpt8c1jIsj4y3tBoRTRqaxuaW1Eo7WMKF
+a7s6KvTBKErPKuzAoIcVB4ir6jm1ticAgB72SScKtPJJdEPemTXRNNzkiw7VbpY9
+QacCAwEAAaNQME4wHQYDVR0OBBYEFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MB8GA1Ud
+IwQYMBaAFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAHVXB5QmZfki9QpKzoiBNfpQ/mo6XWhExLGBTJXEWJT3P7JP
+oR4Z0+85bp0fUK338s+WjyqTn0U55Jtp0B65Qxy6ythkZat/6NPp/S7gto2De6pS
+hSGygokQioVQnoYQeK0MXl2QbtrWwNiM4HC+9yohbUfjwv8yI7opwn/rjB6X/4De
+oX2YzwTBJgoIXF7zMKYFF0DrKQjbTQr/a7kfNjq4930o7VhFph9Qpdv0EWM3svTd
+esSffLKbWcabtyMtCr5QyEwZiozd567oWFWZYeHQyEtd+w6tAFmz9ZslipdQEa/j
+1xUtrScuXt19sUfOgjUvA+VUNeMLDdpHUKHNW/Q=
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+ Eric
+
+
+ Everyone
+ Admins
+
+
+
+
diff --git a/connector/saml/testdata/ca.crt b/connector/saml/testdata/ca.crt
new file mode 100644
index 00000000..00f1cf04
--- /dev/null
+++ b/connector/saml/testdata/ca.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDGTCCAgGgAwIBAgIJAKLbLcQajEf8MA0GCSqGSIb3DQEBCwUAMCMxDDAKBgNV
+BAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNvbTAeFw0xNzA0MDQwNzAwNTNaFw0z
+NzAzMzAwNzAwNTNaMCMxDDAKBgNVBAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNv
+bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKH3dKWbRqCIZD2m3aHI
+4lfBT+u/4DECde74Ggq9WugdTucVQzDZUTaI7wzn17JM9hdPmXvaSRG9BaB1H3uO
+ZCs/fmdhBERRhPvuEVfAZaFfQfR7vn7WvUzT7zwMLLB8+EHzL3fOSGM2QnCOMeUD
+AB27Pb0fuBW43NXaTD9rwfFCHvo1UP+TBJIPnV65HMeMGIrtGLt7MZTPuPm3LnYA
+faXLf2vWSzL5nAgnJvUgceZXmyuciBfXpt8c1jIsj4y3tBoRTRqaxuaW1Eo7WMKF
+a7s6KvTBKErPKuzAoIcVB4ir6jm1ticAgB72SScKtPJJdEPemTXRNNzkiw7VbpY9
+QacCAwEAAaNQME4wHQYDVR0OBBYEFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MB8GA1Ud
+IwQYMBaAFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAHVXB5QmZfki9QpKzoiBNfpQ/mo6XWhExLGBTJXEWJT3P7JP
+oR4Z0+85bp0fUK338s+WjyqTn0U55Jtp0B65Qxy6ythkZat/6NPp/S7gto2De6pS
+hSGygokQioVQnoYQeK0MXl2QbtrWwNiM4HC+9yohbUfjwv8yI7opwn/rjB6X/4De
+oX2YzwTBJgoIXF7zMKYFF0DrKQjbTQr/a7kfNjq4930o7VhFph9Qpdv0EWM3svTd
+esSffLKbWcabtyMtCr5QyEwZiozd567oWFWZYeHQyEtd+w6tAFmz9ZslipdQEa/j
+1xUtrScuXt19sUfOgjUvA+VUNeMLDdpHUKHNW/Q=
+-----END CERTIFICATE-----
diff --git a/connector/saml/testdata/ca.key b/connector/saml/testdata/ca.key
new file mode 100644
index 00000000..05a43130
--- /dev/null
+++ b/connector/saml/testdata/ca.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCh93Slm0agiGQ9
+pt2hyOJXwU/rv+AxAnXu+BoKvVroHU7nFUMw2VE2iO8M59eyTPYXT5l72kkRvQWg
+dR97jmQrP35nYQREUYT77hFXwGWhX0H0e75+1r1M0+88DCywfPhB8y93zkhjNkJw
+jjHlAwAduz29H7gVuNzV2kw/a8HxQh76NVD/kwSSD51euRzHjBiK7Ri7ezGUz7j5
+ty52AH2ly39r1ksy+ZwIJyb1IHHmV5srnIgX16bfHNYyLI+Mt7QaEU0amsbmltRK
+O1jChWu7Oir0wShKzyrswKCHFQeIq+o5tbYnAIAe9kknCrTySXRD3pk10TTc5IsO
+1W6WPUGnAgMBAAECggEBAJUJUDPHIwE7IAo/Drf9UpFvl2wWPmS6n+yKLeRuA0WN
+Gnq27QH5Jqro7BdTCv7NpLEklNYLsar55UCWJacbCn9lSJo2Aqge3yC3GwxFRP9t
+2RHwAAVU8hHM/tmhVkn8ZLDC5o32qlNorVBG+BCEZ0n0bsYlds2+Mq8x1XGSZX7q
+Yyjt02q2VCEDPVUGqR2ONEE98Bv++mUfXzZjGohBPre67PuvEppEwo/uf4ILuyYB
+lusSYcmPD2IBE/7FcRPefb2uDP9c6Tjo8PHXpK5hDBCtLz8lXheYMuTp9GqJmcOk
+kw8af2jNkMUEpFho0RqnrJNQ3A7M5PXQiWxwYSL/2RkCgYEAz4Kg0qm4Oe5jl+4r
+R986nElujo9g9Ad2sy9yT6fqceWoMKf68wh6bMx7HWXRqASS7bJ8wmS9EwgaWLBO
+mjqZax99F1UiFk3+5lNEaYB1OlFaWRsZSapoX6b2JyfEbODqSgKVIaYVTYBHLip3
+3ab/EKNUrNbW9bLSXgbt3aT2kU0CgYEAx9BiErhZqkgmip+4omCWuTr6Lj/awftB
+CVTfwLBYkh7SZcRAWc2bx7a1Bs1rvlczhGYsOlrZXnQRSM4fuUxUb+N5TCzZI9V/
+Prc2r2Lps3AB5CDPLZoyv0efBjSLqAA1tYKTvAHREi9Wfe5PNdfKiwrz6KmIwV3c
++s2YSWcU5MMCgYEArmzvIiTnZkqsDJl2aAOMELLo64w5wuZDMHtBaxOKThLtPXj1
+yDPoNGvtUNi1UrYFiyftFrn29HhrLQGGEL4RF6pwS5yT+ou1J4X2i3gfEdYwS5Yr
+u3AyK7T8VA1pXtvwFCX3lUE1xt989aFdAEPPQv0HwAEWz5Bwo/jPGPABEkECgYBy
+vDWUikbygHuhHhXnJ49kzXjbFc+Hk77EnPferWQug4RM62QILQhGpaNNRKeZpHjw
+jbrXx1MJ6ZwDMlkFDc9ucDA2jYoiCXYHjSzZiPKpFqf/VtegV+rL61RlO8b1sSkm
+ENTEIEbtKkGADldtk3u6W4+zCaZ9YmiBm4zWmVpmAQKBgHvNRcbITib+sbQE+cJM
+4TtrAHFTLWtGCd+n6rKrE8gjt7ypbBOMlOau60LZ2Pbt3DrqOLtDoOalvZhYraOb
+rkoPbDAVaXAmUJ8tw2M07PPLpJuruLSFw16VrBaDiyubO8H/hvnuF4kKpRvt8ty0
+DBogMo9McFczyisRKebmANLw
+-----END PRIVATE KEY-----
diff --git a/connector/saml/testdata/gen.sh b/connector/saml/testdata/gen.sh
new file mode 100755
index 00000000..dec6b158
--- /dev/null
+++ b/connector/saml/testdata/gen.sh
@@ -0,0 +1,47 @@
+#!/bin/bash -ex
+
+# Always run from the testdata directory
+cd "$(dirname "$0")"
+
+# Uncomment these commands to regenerate the CA files.
+#
+# openssl req \
+# -nodes \
+# -newkey rsa:2048 \
+# -keyout ca.key \
+# -new -x509 -days 7300 \
+# -extensions v3_ca \
+# -out ca.crt \
+# -subj "/O=DEX/CN=coreos.com"
+#
+# openssl req \
+# -nodes \
+# -newkey rsa:2048 \
+# -keyout bad-ca.key \
+# -new -x509 -days 7300 \
+# -extensions v3_ca \
+# -out bad-ca.crt \
+# -subj "/O=BAD/CN=coreos.com"
+
+# Sign these files using xmlsec1.
+#
+# Templates MUST have a element already embedded in them so
+# xmlsec1 can know where to embed the signature.
+#
+# See: https://sgros.blogspot.com/2013/01/signing-xml-document-using-xmlsec1.html
+
+xmlsec1 --sign --privkey-pem ca.key,ca.crt --output good-resp.xml good-resp.tmpl
+xmlsec1 --sign --privkey-pem ca.key,ca.crt --output bad-status.xml bad-status.tmpl
+
+# Sign a specific sub element, not just the root.
+#
+# Values match up to the element in the documents.
+xmlsec1 --sign --privkey-pem ca.key,ca.crt \
+ --id-attr:ID Assertion \
+ --output assertion-signed.xml assertion-signed.tmpl
+
+xmlsec1 --sign --privkey-pem ca.key,ca.crt \
+ --id-attr:ID Assertion \
+ --output two-assertions-first-signed.xml \
+ two-assertions-first-signed.tmpl
+
diff --git a/connector/saml/testdata/good-resp.tmpl b/connector/saml/testdata/good-resp.tmpl
new file mode 100644
index 00000000..b3c3c55e
--- /dev/null
+++ b/connector/saml/testdata/good-resp.tmpl
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+ Eric
+
+
+ Everyone
+ Admins
+
+
+
+
diff --git a/connector/saml/testdata/good-resp.xml b/connector/saml/testdata/good-resp.xml
new file mode 100644
index 00000000..3e9b3416
--- /dev/null
+++ b/connector/saml/testdata/good-resp.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ ew38E1LGMwYT+0gUZNq0RacD3GM=
+
+
+ TQ84pCaZAyEDBGkNafTMfwPUWujFvmdoXzyYMXZURIlKhA8Pv1bIZfzQ5MgbQr1W
+z2Ye99/hss24Y4ueNT9nS+53LvDekhNctFGYfgdMjrbxs8Awo3KnbvveDib5zGvk
+fWd/0/QLvlbFd/3670QGb5JQE1nD9mlAqPonyQgoufk63gEM84+tU71cAM7XKiy6
+09MC0y4s967qRAiLAtfgKbvi+46HkF/g+WsS74Wa8cu/A863URt56W0cogRjHWpQ
+B+q8/FyVeJRE0NlrOjhnsgTU2QJtvkxYYvqIpRDbMv53NLKeAFvRhOcyJxhFXtSj
+LF/oPMjbmHji4ylFiAlQWw==
+
+
+MIIDGTCCAgGgAwIBAgIJAKLbLcQajEf8MA0GCSqGSIb3DQEBCwUAMCMxDDAKBgNV
+BAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNvbTAeFw0xNzA0MDQwNzAwNTNaFw0z
+NzAzMzAwNzAwNTNaMCMxDDAKBgNVBAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNv
+bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKH3dKWbRqCIZD2m3aHI
+4lfBT+u/4DECde74Ggq9WugdTucVQzDZUTaI7wzn17JM9hdPmXvaSRG9BaB1H3uO
+ZCs/fmdhBERRhPvuEVfAZaFfQfR7vn7WvUzT7zwMLLB8+EHzL3fOSGM2QnCOMeUD
+AB27Pb0fuBW43NXaTD9rwfFCHvo1UP+TBJIPnV65HMeMGIrtGLt7MZTPuPm3LnYA
+faXLf2vWSzL5nAgnJvUgceZXmyuciBfXpt8c1jIsj4y3tBoRTRqaxuaW1Eo7WMKF
+a7s6KvTBKErPKuzAoIcVB4ir6jm1ticAgB72SScKtPJJdEPemTXRNNzkiw7VbpY9
+QacCAwEAAaNQME4wHQYDVR0OBBYEFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MB8GA1Ud
+IwQYMBaAFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAHVXB5QmZfki9QpKzoiBNfpQ/mo6XWhExLGBTJXEWJT3P7JP
+oR4Z0+85bp0fUK338s+WjyqTn0U55Jtp0B65Qxy6ythkZat/6NPp/S7gto2De6pS
+hSGygokQioVQnoYQeK0MXl2QbtrWwNiM4HC+9yohbUfjwv8yI7opwn/rjB6X/4De
+oX2YzwTBJgoIXF7zMKYFF0DrKQjbTQr/a7kfNjq4930o7VhFph9Qpdv0EWM3svTd
+esSffLKbWcabtyMtCr5QyEwZiozd567oWFWZYeHQyEtd+w6tAFmz9ZslipdQEa/j
+1xUtrScuXt19sUfOgjUvA+VUNeMLDdpHUKHNW/Q=
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+ Eric
+
+
+ Everyone
+ Admins
+
+
+
+
diff --git a/connector/saml/testdata/idp-resp-signed-assertion0.xml b/connector/saml/testdata/idp-resp-signed-assertion0.xml
new file mode 100644
index 00000000..01feb1ca
--- /dev/null
+++ b/connector/saml/testdata/idp-resp-signed-assertion0.xml
@@ -0,0 +1,57 @@
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+ HFNooGfpAONF7T96W3bFsXkH51k=dI0QBihhNT5rtRYE9iB0lEKXkE7Yr4+QueOItRH2RcKwAXJ6DA/m3D/S7qwXk00Hn8ZpHu48ZO+HJpyweEEh2UuUWJCCTwwggagKybbSoRx3UTnSuNAFTdoDWTGt89z8j4+gRMC0sepYwppF3u87vJKRVBh8HjFfrHmWsZKwNtfoeXOOFCeatwxcI1sKCoBs2fTn78683ThoAJe3pygipSHY5WPt4dfT/yAY5Ars+OPY/N02M80OfIygZXdJwND0tVPJIF3M9DaehSkvCBHs7QA7DARsRXcuXdsYY7R8wHzqDVJZ4OvcsprONamm5AgUIpql1CjT94rFwWOFyxF2tg==
+MIIEUTCCAzmgAwIBAgIJAJdmunb39nFKMA0GCSqGSIb3DQEBCwUAMHgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQKEwNJRFAxFDASBgNVBAsTC1NTT1Byb3ZpZGVyMRMwEQYDVQQDEwpkZXYtOTY5MjQ0MRswGQYJKoZIhvcNAQkBFgxpbmZvQGlkcC5vcmcwHhcNMTcwMTI0MTczMTI3WhcNMjcwMTIyMTczMTI3WjB4MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEChMDSURQMRQwEgYDVQQLEwtTU09Qcm92aWRlcjETMBEGA1UEAxMKZGV2LTk2OTI0NDEbMBkGCSqGSIb3DQEJARYMaW5mb0BpZHAub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0X/AE1tmDmhGRROAWaJ82XSORivRfgNt9Fb4rLrf6nIJsQN3vNb1Nk4DSUEDdQuvHNaEemSVkSPgfq5qnhh37bJaghr0728J8dOyYzV5eArPvsbyCRcnhXQzpCK2zvHwjgxNJMsNJLbnYpG/U+dCdCtcOOn9JEhKO8wKn06y2tcrvC1uuVs7bodukPUNq82KJTyvCQP8jh1hEZXeR2siJFDeJj1n2FNTMeCKIqOb42J/i+sBTlyK3mV5Ni++hI/ssIYVbPwrMIBd6sKLVAgInshBHOj/7XcXW/rMf468YtBKs4XnXsE3hLoU02aWCRDlVHa4hm3jfIAqEADOUumklQIDAQABo4HdMIHaMB0GA1UdDgQWBBRjN/dQSvhZxIsHTXmDKQJkPrjp0TCBqgYDVR0jBIGiMIGfgBRjN/dQSvhZxIsHTXmDKQJkPrjp0aF8pHoweDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAoTA0lEUDEUMBIGA1UECxMLU1NPUHJvdmlkZXIxEzARBgNVBAMTCmRldi05NjkyNDQxGzAZBgkqhkiG9w0BCQEWDGluZm9AaWRwLm9yZ4IJAJdmunb39nFKMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIqHUglIUAA+BKMW6B0Q+cqIgDr9fWlsvDwIVK7/cvUeGIH3icSsje9AVZ4nQOJpxmC/E06HfuDXmbT1wG16jNo01mPW9qaOGRJuQqlZdegCSF385o/OHcbaEKBRwyYuvLfu80EREj8wcMUKFpExoaxK7K8DS7hh3w7exLB80jyhIaDEYc1hdyAl+206XpOXSYBetsg7I622R2+ajSL7ygUxQjmKQ5DyInPdXzCFCL6Ew/BN0dwzfnBEEK223ruOWBLpj13zMC077dor/NgYyHZU6iqiDS2eYO5jhVMve/mP9734+6N34seQRmekfmsf2dJcEQhPVYr/j0DeJc3men4=
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://localhost:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+attacker@coreos.com
+
+
+
+
+
+
+ http://localhost:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ attacker
+
+
+ eric.chiang+attacker@coreos.com
+
+
+
+
diff --git a/connector/saml/testdata/okta-resp.xml b/connector/saml/testdata/okta-resp.xml
index 9dff8e10..8b4955b0 100644
--- a/connector/saml/testdata/okta-resp.xml
+++ b/connector/saml/testdata/okta-resp.xml
@@ -1,4 +1,4 @@
-http://www.okta.com/exk91cb99lKkKSYoy0h7Phu93l0D97JSMIYDZBdVeNLN0pwBVHhzUDWxbh4sc6g=M2gMHOmnMAFgh2apq/2jHwDYmisUkYMUqxrWkQJf3RHFotl4EeDlcqq/FzOboJc3NcbKBqQY3CWsWhWh5cNWHDgNneaahW4czww+9DCM0R/zz5c6GuMYFEh5df2sDn/dWk/jbKMiAMgPdKJ2x/+5Xk9q4axC52TdQrrbZtzAAAn4CgrT6Kf11qfMl5wpDarg3qPw7ANxWn2DKzCsvCkOIwM2+AXh+sEXmTvvZIQ0vpv098FH/ZTGt4sCwb1bmRZ3UZLhBcxVc/sjuEW/sQ6pbQHkjrXIR5bxXzGNUxYpcGjrp9HGF+In0BAc+Ds/A0H142e1rgtcX8LH2pbG8URJSQ==MIIDpDCCAoygAwIBAgIGAVjgvNroMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
+http://www.okta.com/exk91cb99lKkKSYoy0h7/jttoTHVc1zHB8tgDVQtiNLAhKAiL24V5Np/SNViPag=y1v4Q0No1l82Y32SHL8weC4mXPWRmhy0SdWPd4Dw1gMWW2aGdnMt11VGom4z1/42HxKB0EBje/UPJeagcpEgJ2JQTdb1SvZrQaxwcWexH0Qyw2Tim9kv66dgr0Uo6PRmkYw/ewcimgdNZUOieffUG1Wc+YWtllmE4nz6NR3aLT9WScbC5smbXk2HwWP9xSg3loKMYTUSH32sRePw76QdGbVExUYyFjnB+oY9mIzBHvCTjZw6JGqEaMBmzReCgLZEBdeo0BuitTWCJY5bayJEpasJCQE4iurcKsz6wMheBbEAcQBqiExSUU8dJgQPhD9y5nMBEGC4cvdq4xbvWBKfVQ==MIIDpDCCAoygAwIBAgIGAVjgvNroMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi05NjkyNDQxHDAaBgkqhkiG9w0BCQEW
DWluZm9Ab2t0YS5jb20wHhcNMTYxMjA4MjMxOTIzWhcNMjYxMjA4MjMyMDIzWjCBkjELMAkGA1UE
@@ -14,7 +14,7 @@ eg2DRW6I9/v/mfN2KAQEDqF9aSNlNFWZWmb52kukMv3tLWw0puaevicIZ/nZrW+D3CLDVVfWHeVt
u/Jh63cVya/VEoP1SVa0XQLf/ial+XuwdBBL1yc+7o2XHOfluDaXw/v2FWYpZtICf3a39giGaNWp
eCT4g2TDWM4Jf/X7/mRbLX9tQO7XRural1CXx8VIMcmbKNbUtQiO8yEtVQ+FJKOsl7KOSzkgqNiL
rJy+Y0D9biLZVKp07KWAY2FPCEtCkBrvo8BhvWbxWMA8CVQNAiTylM27Pc6kbc64pNr7C1Jx1wuE
-mVy9Fgb4PA2N3hPeD7mBmGGp7CfDbGcyhttp://www.okta.com/exk91cb99lKkKSYoy0h7ufwWUjecX6I/aQb4WW9P9ZMLG3C8hN6LaZyyb/EATIs=jKtNBzxAL67ssuzWkkbf0yzqRyZ51y2JjBQ9C6bW8io/JOYQB2v7Bix7Eu/RjJslO7OBqD+3tPrK7ZBOy2+LFuAh3cDNa3U5NhO0raLrn/2YoJXfjj3XX3hyQv6GVxo0EY1KJNXOzWxjp9RVDpHslPTIL1yDC/oy0Mlzxu6pXBEerz9J2/Caenq66Skb5/DAT8FvrJ2s1bxuMagShs3APhC1hD8mvktZ+ZcN8ujs2SebteGK4IoOCx+e8+v2CyycBv1l5l+v5I+D2HnbAw4LfvHnW4rZOJT2AvoI47p1YBK1qDsJutG3jUPKy4Yx5YF73Xi1oytr+rrHyx/lfFPd2A==MIIDpDCCAoygAwIBAgIGAVjgvNroMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
+mVy9Fgb4PA2N3hPeD7mBmGGp7CfDbGcyhttp://www.okta.com/exk91cb99lKkKSYoy0h7W9osU1+7JHYa6E3Y3tvOCBN/jAGVTl39Wngwkq+4jKI=OWa1WvK9+/HOgfm37RwpzUYryJl3ryzdqRUEMlV3ZdLcCz7ZnQ26PCoZD7KxdxUjRci81Ev3OsT8pMCj+sDbFbvBhdRrVvS0sJEgqIFftgD3CYH6OaNGmahSum5Cz+p7xNow/XNQcxjEI2luAtMs+l9JlH8eNPvVVE8RSnXdq9G+y6Iu6RKBVESN9Lgwc6+L2XpqzalZv4d3D+c5dyFCjtNXLOLCJtu3F5w+dYM3KuYJ913S7fbXB2Tv7yRioc9Ssuehft5YacPY9ACsi0PZYAs9Gh4wlzu2yI+7cBfA6hn+h3T/uLu3DMWtHelKtkyOvJS2kFYJlFDio+h7uUbi9A==MIIDpDCCAoygAwIBAgIGAVjgvNroMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi05NjkyNDQxHDAaBgkqhkiG9w0BCQEW
DWluZm9Ab2t0YS5jb20wHhcNMTYxMjA4MjMxOTIzWhcNMjYxMjA4MjMyMDIzWjCBkjELMAkGA1UE
@@ -30,4 +30,4 @@ eg2DRW6I9/v/mfN2KAQEDqF9aSNlNFWZWmb52kukMv3tLWw0puaevicIZ/nZrW+D3CLDVVfWHeVt
u/Jh63cVya/VEoP1SVa0XQLf/ial+XuwdBBL1yc+7o2XHOfluDaXw/v2FWYpZtICf3a39giGaNWp
eCT4g2TDWM4Jf/X7/mRbLX9tQO7XRural1CXx8VIMcmbKNbUtQiO8yEtVQ+FJKOsl7KOSzkgqNiL
rJy+Y0D9biLZVKp07KWAY2FPCEtCkBrvo8BhvWbxWMA8CVQNAiTylM27Pc6kbc64pNr7C1Jx1wuE
-mVy9Fgb4PA2N3hPeD7mBmGGp7CfDbGcyeric.chiang+okta@coreos.comhttp://localhost:5556/dex/callbackurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+mVy9Fgb4PA2N3hPeD7mBmGGp7CfDbGcyeric.chiang+okta@coreos.comhttp://127.0.0.1:5556/dex/callbackurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransporteric.chiang+okta@coreos.comEricEveryoneAdmins
diff --git a/connector/saml/testdata/two-assertions-first-signed.tmpl b/connector/saml/testdata/two-assertions-first-signed.tmpl
new file mode 100644
index 00000000..22f07cda
--- /dev/null
+++ b/connector/saml/testdata/two-assertions-first-signed.tmpl
@@ -0,0 +1,99 @@
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+ Eric
+
+
+ Everyone
+ Admins
+
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+ I AM AN ATTACKER TRYING TO GET YOU TO USE THIS ASSERTION!!!
+
+
+
+
+ Everyone
+ Admins
+
+
+
+
diff --git a/connector/saml/testdata/two-assertions-first-signed.xml b/connector/saml/testdata/two-assertions-first-signed.xml
new file mode 100644
index 00000000..ccc363b4
--- /dev/null
+++ b/connector/saml/testdata/two-assertions-first-signed.xml
@@ -0,0 +1,122 @@
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ kDdpmKMPp7zjUeMTuntXJFpT6cs=
+
+
+ Q12w9zPo9Bqn3W2OT7lbFbhfIDQrp7SXd/+9ZWpY4mv3ApgaOcNX2VtpSE0EjorU
+1NyrktVOkCYueJm/HVQF7gyF85KRlPBDLBZOwxbnnmrRFoCk+U2kjIt8k8eZ7NsD
+jLFGFgEveS359uvaHZR1Exbr0PBYwS7aXR3fpmjMjZ9T8f8Oe3Nt/9nWPgz/dFhb
+Aa+AniWuupfq2v6YMLZ+9GLiO0sOr8UVkW8AYOm2Bin30epikXT1Axi/VxWz/fjP
+nMUkgusFnhkgmIf/YncAv4S9GY6DcaV2iEj6cL70S7pcgaeRFi3iozigl+9a+lFo
+dt3Jy8Jq/N3OAyDP2DxLEw==
+
+
+MIIDGTCCAgGgAwIBAgIJAKLbLcQajEf8MA0GCSqGSIb3DQEBCwUAMCMxDDAKBgNV
+BAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNvbTAeFw0xNzA0MDQwNzAwNTNaFw0z
+NzAzMzAwNzAwNTNaMCMxDDAKBgNVBAoMA0RFWDETMBEGA1UEAwwKY29yZW9zLmNv
+bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKH3dKWbRqCIZD2m3aHI
+4lfBT+u/4DECde74Ggq9WugdTucVQzDZUTaI7wzn17JM9hdPmXvaSRG9BaB1H3uO
+ZCs/fmdhBERRhPvuEVfAZaFfQfR7vn7WvUzT7zwMLLB8+EHzL3fOSGM2QnCOMeUD
+AB27Pb0fuBW43NXaTD9rwfFCHvo1UP+TBJIPnV65HMeMGIrtGLt7MZTPuPm3LnYA
+faXLf2vWSzL5nAgnJvUgceZXmyuciBfXpt8c1jIsj4y3tBoRTRqaxuaW1Eo7WMKF
+a7s6KvTBKErPKuzAoIcVB4ir6jm1ticAgB72SScKtPJJdEPemTXRNNzkiw7VbpY9
+QacCAwEAAaNQME4wHQYDVR0OBBYEFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MB8GA1Ud
+IwQYMBaAFNHyGYyY2+eZ1l7ZLPZsnc3GOtj/MAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAHVXB5QmZfki9QpKzoiBNfpQ/mo6XWhExLGBTJXEWJT3P7JP
+oR4Z0+85bp0fUK338s+WjyqTn0U55Jtp0B65Qxy6ythkZat/6NPp/S7gto2De6pS
+hSGygokQioVQnoYQeK0MXl2QbtrWwNiM4HC+9yohbUfjwv8yI7opwn/rjB6X/4De
+oX2YzwTBJgoIXF7zMKYFF0DrKQjbTQr/a7kfNjq4930o7VhFph9Qpdv0EWM3svTd
+esSffLKbWcabtyMtCr5QyEwZiozd567oWFWZYeHQyEtd+w6tAFmz9ZslipdQEa/j
+1xUtrScuXt19sUfOgjUvA+VUNeMLDdpHUKHNW/Q=
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+ Eric
+
+
+ Everyone
+ Admins
+
+
+
+
+
+ http://www.okta.com/exk91cb99lKkKSYoy0h7
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+
+
+ http://127.0.0.1:5556/dex/callback
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
+ eric.chiang+okta@coreos.com
+
+
+
+
+ I AM AN ATTACKER TRYING TO GET YOU TO USE THIS ASSERTION!!!
+
+
+
+
+ Everyone
+ Admins
+
+
+
+