Giter Club home page Giter Club logo

gosaml2's People

Contributors

andrewstuart avatar arun251 avatar beyang avatar cbarcenas avatar dependabot[bot] avatar fatlotus avatar klizhentas avatar loafoe avatar mfridman avatar michaelschiff avatar moorereason avatar nicksnyder avatar ottob avatar phoebesimon avatar pradeephkcisco avatar probakowski avatar ptman avatar radeksimko avatar remilapeyre avatar russellhaering avatar russjones avatar ryicoh avatar sam-mt avatar ubalogun-arista avatar unknwon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gosaml2's Issues

Metadata struct only stores one endpoint

First, thanks for the great library. My issue: The struct to store metadata is

type EntityDescriptor struct {
	XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:metadata EntityDescriptor"`
	// SAML 2.0 8.3.6 Entity Identifier could be used to represent issuer
	EntityID         string           `xml:"entityID,attr"`
	IDPSSODescriptor IDPSSODescriptor `xml:"IDPSSODescriptor"`
}

and then the IDPSSODescriptor struct is

type IDPSSODescriptor struct {
	XMLName             xml.Name            `xml:"urn:oasis:names:tc:SAML:2.0:metadata IDPSSODescriptor"`
	KeyDescriptors      []KeyDescriptor     `xml:"KeyDescriptor"`
	NameIDFormats       []NameIDFormat      `xml:"NameIDFormat"`
	SingleSignOnService SingleSignOnService `xml:"SingleSignOnService"`
	Attributes          []Attribute         `xml:"Attribute"`
}

That means that there can only be one instance of a SingleSignOnService struct. However, IDPs are allowed to provide multiple endpoints with different bindings. For example, this is (scrubbed) metadata I got from OneLogin:

<EntityDescriptor entityID="https://app.onelogin.com/saml/metadata/000">
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <KeyDescriptor use="signing">
        <KeyInfo>
            <X509Data>
                <X509Certificate>...</X509Certificate>
            </X509Data>
        </KeyInfo>
    </KeyDescriptor>
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://site.onelogin.com/trust/saml2/http-redirect/slo/00000"/>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://site.onelogin.com/trust/saml2/http-redirect/sso/000"/>
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://site.onelogin.com/trust/saml2/http-post/sso/000"/>
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://site.onelogin.com/trust/saml2/soap/sso/000"/>
</IDPSSODescriptor>
</EntityDescriptor>

As it stands, unmarshalling picks one of the endpoints, and I don't get the information for the rest. Adding [] to the struct so that it can store multiple SingleSignOn instances would essentially fix the issue I think. Thoughts?

SLO Example

Hi,

I've noticed that some structs and funcs exist to manage SLO but I haven't found how to use them. Could you please share an example ?

Security policy link not working

The link in SECURITY.md is broken, it returns a 404 Not Found when I click the link. I think you may have accidentally disabled private reporting in Settings (docs), as I don't see the button present in the Security tab for this repository but can see it on other repositories.

Clock skew for service provider

If the IdP and SP times are out of sync, then the SP may end up mistaking a valid SAML assertion as invalid. Therefore, we should be able to specify a clock skew to use for the service provider so that values within clock skew range of the NotBefore, NotOnOrAfter, or SessionNotOnOrAfter constraints are treated as valid.

Thank you

This is not requesting a feature or reporting a defect.

I have wasted so much time trying to get SAML working for Go web services. Other libraries haven't seemed to work or worked properly with one IdP but not with others, providing no insight as to why.

This package worked with minimal fuss. I'm grateful to have it.

Group AttributeStatement is incorrectly handled if multiple groups are sent.

I have a Okta Application that has some people configured as part of multiple groups. In the SAMLResponse I do see the data: (Groups field has "QA", "Dev" and "Everyone".

Groups: {XMLName:{Space:urn:oasis:names:tc:SAML:2.0:assertion Local:Attribute} FriendlyName: Name:Groups NameFormat:urn:oasis:names:tc:SAML:2.0:attrname-format:basic Values:[{XMLName:{Space:urn:oasis:names:tc:SAML:2.0:assertion Local:AttributeValue} Type: Value:QA} {XMLName:{Space:urn:oasis:names:tc:SAML:2.0:assertion Local:AttributeValue} Type: Value:Everyone} {XMLName:{Space:urn:oasis:names:tc:SAML:2.0:assertion Local:AttributeValue} Type: Value:Dev}]}

However, since the library is treating everything like a key / value strings, only the last group gets attached. i.e. attributeStatement["Groups"] is "QA" (one of them)

This is probably a generic problem for handling attribute Statements where we could expect a list and not just a string.

Solution: We need to support arrays if the attribute statement is a Array. I haven't thought the solution through yet but will give it shot and send a PR :)

How do i generate SP MetaData File Using gosaml2

Hi,
how do i generate the service provider metadata file that needs to be shared with the IDP

Is there is way that i can generate below meta data file using gosaml2 that needs to share with the IDP

<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" validUntil="2021-07-27T11:19:13.559Z" entityID="http://localhost:8001/saml/metadata"> <SPSSODescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" validUntil="2021-07-27T11:19:13.55852Z" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" AuthnRequestsSigned="false" WantAssertionsSigned="true"> <KeyDescriptor use="encryption"> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <X509Data> <X509Certificate>MIICvDCCAaQCCQCujMRKGshPODANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVteXNlcnZpY2UuZXhhbXBsZS5jb20wHhcNMjEwNzI1MTExODExWhcNMjIwNzI1MTExODExWjAgMR4wHAYDVQQDDBVteXNlcnZpY2UuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDruv/Q6k4TZFnG/vDd060iuRviN2yM0J92nXNn2g3c/g3oqiB9eom/1mRUKOeHOhOFjC18m/nOeNss6RXjkWezIuhzYNKP0ABfhCT1pdVOTI8uBag9aXFPYsyRt+mV6qrJ6pNTzYkWpub0dfMuY1XDkW46Zp6YvAf/UVyfGTq0ZkX0WjrrZJOjaYcWajJ73xm5ZZuoX4KTQmbx7ctVkHsKk9SXFnSkaj1iEdqyg2pwGiG89FGhX731O178V5duLzUAh1bLyEKZKAkofpDWQptrdbP9ztbvVYHKj3dtqnYLjQadfMiX3EDV4RKo86CKbFC7NSy/H0gOtkkYhL9R/VtHAgMBAAEwDQYJKoZIhvcNAQELBQADggEBABw9BVBsJpcGGf7W9i+xaFsebb798TomoD2k5vNqJFi3ShpUAsqR4Zc1I9M4lPUPxFBBE+tpD1cVS6QQIfY62ql7ycd50Ma3CejkCW9DuOQ56X6hFIZl6TeZ0vv7T37m3F+URt7SXflRcn8VEQ1UidEc9VOD/E/1zgBkeniXkBXKgh5MYmUMfTF+flacNl1lBVFiibaD32aaVC97EqfdItcnlKvh7fYGiPAWFRoRrcJfKM1nurAt4kNEdpd/QncGQ2etUbkq3tBLczCRUdFKq1YYAmXVnZUZC6PM4+k/IPzR7xEdjZk1FEFNHTwOXLyxo3ZDlHmMcTvWlT93D7DXaqY=</X509Certificate> </X509Data> </KeyInfo> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"></EncryptionMethod> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"></EncryptionMethod> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"></EncryptionMethod> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"></EncryptionMethod> </KeyDescriptor> <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8001/saml/slo" ResponseLocation="http://localhost:8001/saml/slo"></SingleLogoutService> <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8001/saml/acs" index="1"></AssertionConsumerService> </SPSSODescriptor> </EntityDescriptor>

Missing exported function BuildAuthURLWithRedirect

Hello thank you for this Library!

I need to use this library with PingOne and with signed authentication requests. There is currently no exported function to build an Auth URL with the HTTP Redirect Binding.

The current function BuildAuthURL calls the function BuildAuthURLFromDocument which has this singular line of code:

return sp.buildAuthURLFromDocument(relayState, BindingHttpPost, doc)

Unless this is a bug and it's supposed to call BindingHttpRedirect, the library appears to be missing the exported function BuildAuthURLWithRedirect

I have a PR in my personal Git with the requested changes: https://github.com/TheGreatAbyss/gosaml2/pull/1/files

If you would grant me access to the repo I'd be happy to push a branch and open a MR.

Thank You
-- Eric

Harmonize etree and encoding/xml

Following up on Andrew's comment on #10. Russell, stylistic preferences between etree and encoding/xml? (I too like keeping with the stdlib, but it's not my library.)

Anyway, if you do have an opinion one way or another, I'd be happy to start poking at things.

Keycloak

I'm trying to use gosaml2 with JBoss Keycloak.

I'm consuming the descriptor metadata but I'm getting this error when running xml.Unmarshal:

expected element type <EntityDescriptor> but have <EntitiesDescriptor>

SPKeyStore

Is there any actual examples of SPKeyStore being set to a valid keystore? It's really confusing how to make this field consume some sort of keystore, preferably a JKS file.

Proposal: integrate efforts/packages

So, I've been doing a bit of work with your library after seeing that you got much further than I ever did on the signature verification front. I'm currently working on integrating with Shibboleth and will likely have a few pull requests at least to enable better integration with Shib.

Eventually, though, I got to the point where I realized that you haven't yet added any decryption capability, which is essentially all I got working in my library (though it only implements a few specific decryption schemes for the Shib version I'm using).

I had gotten through the decryption piece and, excited about my progress, was promptly stopped in my tracks by the complexity of xmldsig, xmlc14n, etc. Looks like you got that hard part done where I gave up, though! :-)

I wanted to touch base and see what you would think about integrating efforts since it seems like there's very little overlap -- almost as if it was planned. I figure it'd mostly look like me merging my code into your codebase to support decrypting encrypted assertions, since you've got a little more traction (7 stars to my 0).

Let me know what you think! :-)

Decrypt assertion returns wrong error value

In decode_response.go post decryption if there is an error in deflating the xml post decryption then the handler returns the error from decryption which will always be nil. It should return the error in parsing the decrypted XML

	raw, derr := encryptedAssertion.DecryptBytes(decryptCert)
	if derr != nil {
		return fmt.Errorf("unable to decrypt encrypted assertion: %v", derr)
	}

	doc, _, err := parseResponse(raw)
	if err != nil {
		return fmt.Errorf("unable to create element from decrypted assertion bytes: %v", derr)
	}

After parseResponse, it returns derr which will always be nil whereas it should be returning err. Is this a wrong expectation or am I missing something here?

Add proper documentation on different functions available

Thank you for this package.

I was using this package and realized that it lacked proper documentation. For a start, there could at least be a list of functions in the package. I had to dig through the code to find the functions that I wanted to use. It would be really helpful to have a list of functions available in README.

Having an example of the implementation of each of the functions would immensely help developers who use this package.

validate does not check SessionNotOnOrAfter for expiration

Hi, there,
I had an issue while importing this lib for our current SAML token validation. Our current lib also check SessionNotOnOrAfter for expiration. If NotOnOrAfter or SessionNotOnOrAfter is not expired, the SAML token is valid.
Do you think this is a valid request to make the changes to the following code? If not, can we add a flag to skip the following code? So we can handle the expiration logic properly in application layer.
now := sp.Clock.Now()
if now.After(notOnOrAfter) {
return ErrInvalidValue{
Reason: ReasonExpired,
Key: NotOnOrAfterAttr,
Expected: now.Format(time.RFC3339),
Actual: subjectConfirmationData.NotOnOrAfter,
}
}

assertionInfo.WarningInfo.InvalidTime using time finer than milliseconds

In VerifyAssertionConditions in validate.go, notBefore and notOnOrAfter are doing time comparison finer than milliseconds.
According to SAML Core spec

1.3.3 Time Values
All SAML time values have the type xs:dateTime, which is built in to the W3C XML Schema Datatypes
specification [Schema2], and MUST be expressed in UTC form, with no time zone component.
SAML system entities SHOULD NOT rely on time resolution finer than milliseconds. Implementations
MUST NOT generate time instants that specify leap seconds.

TIme comparisons SHOULD NOT rely on time resolution finer than milliseconds.

In our case, the now clock returned 20:08:46.518691 and the notBefore SAML assertion had 20:08:46.55 which triggered the warning. The library should at most compare one significant digit after the seconds dot.

This is a major issue that causes intermittent login failure for users.

IdentityProviderSSOBinding and buildAuthnRequest

There is a string member IdentityProviderSSOBinding in the SAMLServiceProvider struct, which doesn't seem to be used anywhere.
And in buildAuthnRequest there is no way to set ProtocolBinding to anything other than HTTP-POST. Was the IdentityProviderSSOBinding field expected to be used here?

What is SPKeyStore used for?

I'm trying to understand why we need to provide a certificate to create AuthnRequests. So far, I've generated a random one using dsig.RandomKeyStoreForTest(), and haven't imported this anywhere into my IDP, but everything is working smoothly - so I'm wondering what purpose it serves.

I'm assuming its for a more complex use case?

SP Metadata generation

Hello, Is there any way I can get metadata XML string from the library? It is usually used in order to integrate with IdP and contains information like entity name, public key, assertion consumer endpoint etc.

Possible Vulnerability: Auth Request sends the service providers validation certificate

The signature in the auth request in signed using the service providers private key and the validation is to be done with public certificate which should be exclusively with the Idp but this certificate is sent in the Auth Request.

Is this behavior correct as we are in the understanding that the public certificate sent in the request should be that of the Identity Provider for Identification purposes and not the one of the Service Provider which would be used for signature validation as all the required information for deciphering the auth request would then be in it.

This is the actual validation certificate being sent in the request

auth-req-cert

Sample xml here

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    AssertionConsumerServiceURL="https://localhost:10443/v1/samlacsendpoint"
                    Destination="https://auth.pingone.asia/793adfb9-e7c9-4e80-a1a2-335f27066ffe/saml20/idp/sso"
                    ID="_c46eb447-c2e0-4dcf-b2a3-ba54961e6bcf"
                    IssueInstant="2023-11-16T13:43:35Z"
                    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                    Version="2.0"
                    >
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://example.com/saml/acs/example</saml:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
            <ds:Reference URI="#_c46eb447-c2e0-4dcf-b2a3-ba54961e6bcf">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                <ds:DigestValue>hUi2n9LKrdfhgOPawzk7SMMxCC3Pm1Ayusup34CQ5pw=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>eaV6UNp+M6e0yifSPTqE3x5RAt3Mp14DuEqatLzkU2kA9tfjEJJkZsFQkjiSr7G+dIfqg5yzbT2fVIMToLEqrFJRU1zhFPXtz8+OwEZ2xzpW3k6DhDxwcVRRZbW7JhOD/qieYw9kDUDhAWbpmhU4QeFhnqMkrKCF5tqVtK0HOk/Z6wFEDopJGJ7OnPJAp57sfv+Lg6knw5qyz7lkx6WuPLJh6DygUYRWcZD2izV9iqinAAVI2pqWuE4uZIXvvF6vkyj1OfAV7b2d0RKrMt9ZuC3TpzxFEau3r9xxQ26iHrYRxrLE6I9nQT0V7GbNMAQzH9+x0x0pmfbWq2CWby9SSQ==</ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509Certificate>MIID1zCCAr+gAwIBAgIUGLf0PTJTRxdcPtHTRCksRL0b9IswDQYJKoZIhvcNAQELBQAwezELMAkGA1UEBhMCSU4xDDAKBgNVBAgMA0dvYTEOMAwGA1UEBwwFVmVybmExEzARBgNVBAoMClBlcnNpc3RlbnQxDDAKBgNVBAsMA0libTErMCkGCSqGSIb3DQEJARYcY3lydXNfZnVydGFkb0BwZXJzaXN0ZW50LmNvbTAeFw0yMzEwMDkxMTQ5NDZaFw0yNDA0MDYxMTQ5NDZaMHsxCzAJBgNVBAYTAklOMQwwCgYDVQQIDANHb2ExDjAMBgNVBAcMBVZlcm5hMRMwEQYDVQQKDApQZXJzaXN0ZW50MQwwCgYDVQQLDANJYm0xKzApBgkqhkiG9w0BCQEWHGN5cnVzX2Z1cnRhZG9AcGVyc2lzdGVudC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2H1meXHs2/bc91+AD2QDiXN6MW4T3EkdT9O4m2xYyifd19ufKjU+nqeCp0j6S7q1RiG3L5MkgJLL4I6ar26Mpv9fHQlG6jhnVzh7Ks21xzhem+SjokxgbyFYDOVPD3B/yyZ7uWmQS9bsmwWeDym1Zsgb4jURl0OuWauu93mPyrUwHXZlUQBF8tcs1/uD+IyAGWeurBm9WEpoPRb9ur7YNlAQxqxMSfh8nIYpywHOPUrRXEX6yDAGsju85UANlbSwEBr8CTF7OkEF7NLxT/gESN0D8M8ZBwAEGxA5J6d//SXpqiLDt1ZfsBB2f27wO3c4s+OOGNvdq57yiYc7+mx3tAgMBAAGjUzBRMB0GA1UdDgQWBBQ5+yobfvbsYodF42pwYG5WQKiyRzAfBgNVHSMEGDAWgBQ5+yobfvbsYodF42pwYG5WQKiyRzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBe+TuprCYWSd/0SV910Gylg6OkPdMmh7Iuum87cwQSvL0PCpe2V531mvqXcWmeeetB1ABAX38TUdG9watNxJyZPELXGqc29YwHZQ28iOpWH3GXtm73mjXfF9L2up9tgc9AbVsG7WlZp8eTE/HdLLVKsFCG02cww57mCl+Ob2OLwCm+cfr2K5aceSk/6yvP+N5W1fajFtf0PLrt7RyQ2M8k+ySvSCHPED4VEZjJo5xUCH3CS+ooHkIHBHq+Ef6WRXA+DNLxvXppko7EKTIurG6gm5Q6zwaBfExbgWHSobs2BVlZBLvUuMhY6HAbXlan0T+lZvXC2kvgy+BULIPKziX3</ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </ds:Signature>
    <samlp:NameIDPolicy AllowCreate="true" />
</samlp:AuthnRequest>

Build signature query parameters do not obey prescribed order

First of all, thanks for creating this library--we've found it incredibly useful for providing SAML support to enterprise customers of Sourcegraph!

The SAML 2.0 errata specifies an order to the query parameters in the build signature (https://www.oasis-open.org/committees/download.php/56779/sstc-saml-bindings-errata-2.0-wd-06.pdf):

image

This library uses the Go stdlib url.Values.Encode method, which orders query parameters alphabetically. Apparently this relied upon by some SAML implementations: sourcegraph/sourcegraph#121.

Happy to submit a PR for this!

Crash on nil-pointer dereference with malformed input

I've been doing a bit of fuzzing of this package with go-fuzz. I captured a valid SAML response from Okta and then had go-fuzz mutate it. I have fuzzing implemented on this branch https://github.com/stevenjohnstone/gosaml2/tree/sjj/fuzzing.

Here's the panic in a simple test program:

package main

import (
	"crypto/x509"
	"encoding/base64"
	"encoding/xml"
	"time"

	saml2 "github.com/russellhaering/gosaml2"
	"github.com/russellhaering/gosaml2/types"
	dsig "github.com/russellhaering/goxmldsig"
)

const (
	timeString   = "2019-08-12T12:00:52.718Z"
	oktaMetadata = `<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor entityID="http://www.okta.com/exk133onomIuOW98z357" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"><md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>MIIDpDCCAoygAwIBAgIGAWxzAwX1MA0GCSqGSIb3DQEBCwUAMIGSMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi05MDUyNTExHDAaBgkqhkiG9w0BCQEW
DWluZm9Ab2t0YS5jb20wHhcNMTkwODA4MjA1MzMzWhcNMjkwODA4MjA1NDMzWjCBkjELMAkGA1UE
BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtOTA1MjUxMRwwGgYJ
KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
m+ZZF6aEG6ehLLIV6RPA+i1z6ss3HBG2bZD3efwKCDDXYUkp59AE7JsjVHMtpJPHhzHuScuHDMlu
HmkBQTW7j9XpnaRn8SfZXkwlCUHTo+HAC9lwbQxO4d4wnwgnm6FAjm1I/gbfFAobd8BR9pDxHuXE
MQ0DtQu/W3WbDUrz/bhSxPJAoVy2koQn9G0y3unm7eRwYWHeuW6GdPWV2szTtDS0c3qtUXVF5Ugg
iQYlwQu6xkfy4l8iGJL7ETa2BmJzwCFecMIct87SqNhYQwCBH54MBaHcaSsCKyimNvMY9B7RmC+H
4+awePPA1q3R/UQ3Pfom8mx6yDdKIWqlkG3MsQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAiURCZ
P4oJWcf1o5nm4yG15UH01g/S6Y4OUWMi6BFJy9fCrJ0h/2BZKi68SQ0uMAbdK6anxCzq3Rr5MSzW
OWPQ1Zljn3LGPsiTFdFca/GVRen5IYQ7Dr2Mvhtm+QVscEY9TDjtETbTAHEVEjwXmB21wtdIhizv
sQS7wz0A8LV+Atpbev45RiV6COmB6T6vJuFQ7ZsDZMSHZriTYiETTJvHBGd7PtbCxYNc6LRB2JDb
wlekRhVEjR0UhnM+nn2sqqbv7tDEPs63lZSDXCnR1PhscHrEuQ04rHI3OL0gCULVQFvJrj85IAZF
1QQuGUK8ozfOyFpQWAJUW71INnF/SLWv</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://dev-905251.okta.com/app/medev905251_test_1/exk133onomIuOW98z357/sso/saml"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://dev-905251.okta.com/app/medev905251_test_1/exk133onomIuOW98z357/sso/saml"/></md:IDPSSODescriptor></md:EntityDescriptor>`

	badInput = `<saml2:Assertion ID="id1684056077776386493060641"IssueInstant="2019-08-12T12:00:52.718Z"Version="2.0"xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"xmlns:xs="http://www.w3.org/2001/XMLSchema"><saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"xmlns="">http://www.okta.com/exk133onomIuOW98z357</l><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#id1684056077776386493060641"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces PrefixList="xs"xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/></m></s><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>dC1cm0pLLjIWZC6G2Pmf0JogmqHztp9W1euXPd/TUHo=</e></e></o><ds:SignatureValue>YRSCFLIkIgjbbYLyfCIc8jsP2MUJPjn+nYWRdlVIDdXtYXXxklYqdBXQsxDwNcsOAIGS75PeVGryml3oBkUDg/MfK7z/fFPLXX7c7xgh7/DBAFlSXbwlJQxuXQ5eZcGesgG6nYRwU1hpW+yN7C2ODN9KHi5TUdiEhvy8vdlFSfxdy4Mn68nG/UZBqmHHIZdRG2/Hpcs29YyaVVZUCZ0w22b7zsPuOXHuStOSTQ6isxI2R268+ZNKERYaNMCAGX4zNlT3mHBV0NnZkbO3wmlOfKksL+Qx7L64xFc3PaervxWuPqh2FoWpTCqFdliLdvUfFDszKXJKhO0bj1U0aSrdzg==</e><s><s><s></X></X></o></e><saml2:Subject xmlns=""><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">[email protected]</l><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml2:SubjectConfirmationData InResponseTo="_40a419f5-5c1c-43d0-5834-5caf268a5f01"NotOnOrAfter="2019-08-12T12:05:52.718Z"Recipient="https://127.0.0.1/login"/></l></l><saml2:Conditions NotBefore="2019-08-12T11:55:52.718Z"NotOnOrAfter="2019-08-12T12:05:52.718Z"xmlns=""><saml2:AudienceRestriction><saml2:Audience>37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f.jazznetworks.com</l></l></l><saml2:AuthnStatement AuthnInstant="2019-08-12T12:00:52.718Z"SessionIndex="_40a419f5-5c1c-43d0-5834-5caf268a5f01"xmlns=""><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</l></l></l><saml2:AttributeStatement xmlns=""><saml2:Attribute Name="FirstName"NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"><saml2:AttributeValue xmlns=""xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:type="xs:string">Steven</l></l><saml2:Attribute Name="LastName"NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"><saml2:AttributeValue xmlns=""xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:type="xs:string">Johnstone</l></l><saml2:Attribute Name="Email"NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"><saml2:AttributeValue xmlns=""xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:type="xs:string">[email protected]`
)

func newServiceProvider() *saml2.SAMLServiceProvider {
	metadata := &types.EntityDescriptor{} // may need to support EntityDescriptors (plural)
	if err := xml.Unmarshal([]byte(oktaMetadata), metadata); err != nil {
		panic(err)
	}

	certStore := dsig.MemoryX509CertificateStore{
		Roots: []*x509.Certificate{},
	}

	for _, kd := range metadata.IDPSSODescriptor.KeyDescriptors {
		for _, xcert := range kd.KeyInfo.X509Data.X509Certificates {
			if xcert.Data == "" {
				panic("nope")
			}
			certData, err := base64.StdEncoding.DecodeString(xcert.Data)
			if err != nil {
				panic(err)
			}

			idpCert, err := x509.ParseCertificate(certData)
			if err != nil {
				panic(err)
			}

			certStore.Roots = append(certStore.Roots, idpCert)
		}
	}

	SSOs := metadata.IDPSSODescriptor.SingleSignOnServices

	tenantURI := "test.example.com"

	fakeTime, err := time.Parse(time.RFC3339, timeString)
	if err != nil {
		panic(err)
	}

	clock := dsig.NewFakeClockAt(fakeTime)

	return &saml2.SAMLServiceProvider{
		Clock:                       clock,
		IdentityProviderSSOURL:      SSOs[0].Location,
		IdentityProviderIssuer:      metadata.EntityID,
		ServiceProviderIssuer:       tenantURI,
		AssertionConsumerServiceURL: "https://127.0.0.1/login",
		SignAuthnRequests:           true,
		AudienceURI:                 tenantURI,
		IDPCertificateStore:         &certStore,
		ValidateEncryptionCert:      true,
	}
}

func main() {
	base64Input := base64.StdEncoding.EncodeToString([]byte(badInput))
	if _, err := newServiceProvider().RetrieveAssertionInfo(base64Input); err != nil {
		_ = err
	}
}
panic: runtime error: invalid memory address or nil pointer dereference                                                                                                                                                                                                                                                                                                                
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x6727e6]                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                       
goroutine 1 [running]:                                                                                                                                                                                                                                                                                                                                                                 
github.com/russellhaering/gosaml2.(*SAMLServiceProvider).validateAssertionSignatures.func1(0xc000179f20, 0xc000182ea0, 0x9, 0x1)                                                                                                                                                                                                                                                       
    /goroot/go/src/github.com/russellhaering/gosaml2/decode_response.go:170 +0x56                                                                                                                                                                                                                                                                                                      
github.com/russellhaering/goxmldsig/etreeutils.NSFindIterateCtx.func1(0xc000179f20, 0xc000182ea0, 0xc000179f20, 0x0)                                                                                                                                                                                                                                                                   
    /goroot/go/src/github.com/russellhaering/goxmldsig/etreeutils/namespace.go:281 +0x137                                                                                                                                                                                                                                                                                              
github.com/russellhaering/goxmldsig/etreeutils.NSTraverse(0xc0000ccc60, 0xc000182ea0, 0xc000179ef0, 0x30, 0x6ebda0)                                                                                                                                                                                                                                                                    
    /goroot/go/src/github.com/russellhaering/goxmldsig/etreeutils/namespace.go:148 +0x6e                                                                                                                                                                                                                                                                                               
github.com/russellhaering/goxmldsig/etreeutils.NSFindIterateCtx(0xc0000ccc60, 0xc000182ea0, 0x71c4db, 0x25, 0x712a6e, 0x9, 0xc000179ec0, 0x7152bf, 0x12)                                                                                                                                                                                                                               
    /goroot/go/src/github.com/russellhaering/goxmldsig/etreeutils/namespace.go:268 +0xa4                                                                                                                                                                                                                                                                                               
github.com/russellhaering/goxmldsig/etreeutils.NSFindIterate(...)                                                                                                                                                                                                                                                                                                                      
    /goroot/go/src/github.com/russellhaering/goxmldsig/etreeutils/namespace.go:257                                                                                                                                                                                                                                                                                                     
github.com/russellhaering/gosaml2.(*SAMLServiceProvider).validateAssertionSignatures(0xc000166000, 0xc000182ea0, 0x0, 0x0)                                                                                                                                                                                                                                                             
    /goroot/go/src/github.com/russellhaering/gosaml2/decode_response.go:200 +0xed                                                                                                                                                                                                                                                                                                      
github.com/russellhaering/gosaml2.(*SAMLServiceProvider).ValidateEncodedResponse(0xc000166000, 0xc000145000, 0xf80, 0xc000013510, 0xc000160000, 0xc0000d8b40)                                                                                                                                                                                                                          
    /goroot/go/src/github.com/russellhaering/gosaml2/decode_response.go:248 +0x30e                                                                                                                                                                                                                                                                                                     
github.com/russellhaering/gosaml2.(*SAMLServiceProvider).RetrieveAssertionInfo(0xc000166000, 0xc000145000, 0xf80, 0xba0, 0xc000145000, 0xf80)                                                                                                                                                                                                                                          
    /goroot/go/src/github.com/russellhaering/gosaml2/retrieve_assertion.go:40 +0x9b                                                                                                                                                                                                                                                                                                    
main.main()                                                                                                                                                                                                                                                                                                                                                                            
    /goroot/go/src/github.com/russellhaering/gosaml2/crasher/main.go:92 +0xaa                                                                                                                                                                                                                                                                                                          
exit status 2

Appears to be unverified assertions can have nil parents. Appears to be fixed with this patch:

index a40e4b1..0804962 100644
--- a/decode_response.go
+++ b/decode_response.go
@@ -6,6 +6,7 @@ import (
        "crypto/tls"
        "crypto/x509"
        "encoding/base64"
+       "errors"
        "fmt"
        "io/ioutil"
 
@@ -166,7 +167,11 @@ func (sp *SAMLServiceProvider) validateAssertionSignatures(el *etree.Element) er
        signedAssertions := 0
        unsignedAssertions := 0
        validateAssertion := func(ctx etreeutils.NSContext, unverifiedAssertion *etree.Element) error {
-               if unverifiedAssertion.Parent() != el {
+               parent := unverifiedAssertion.Parent()
+               if parent == nil {
+                       return errors.New("parent is nil")
+               }
+               if parent != el {
                        return fmt.Errorf("found assertion with unexpected parent element: %s", unverifiedAssertion.Parent().Tag)
                }
 

Inconsistent Handling of Expired Responses

Hi, I'm back with another request, although this one is less cut and dry. The WarningInfo struct has a warning InvalidTime that's used while processing Assertions, which was going to be very useful for me. But I found out that the InvalidTime warning is only thrown when the Assertion Conditions NotOnOrAfter is violated (validate.go line 79). If, on the other hand, the Assertion SubjectConfirmation NotOnOrAfter is violated, the library returns an error (validate.go line 206). These two seem like the same class of problem to me, so I was wondering if there was a reason why they were handled differently, and if it was possible for both of them to be warnings?
Thanks!

HTTP-Redirect: Missing Signature and SigAlg parameters in SAMLRequest Url (AuthNRequest)

I'm using the latest gosaml2 and noticed that my identity provider (Keycloak) does not accept the signed AuthNRequest.

The reason is:

But it seems that the Redirect binding authUrl does not have SigAlg and Signature parameters, even though setting SignAuthnRequests to true and SPKeyStore to my own Keystore.

reference: spring-projects/spring-security#7711

[CVE-2020-7731] CWE-476: NULL Pointer Dereference?

https://ossindex.sonatype.org/vulnerability/CVE-2020-7731?component-type=golang&component-name=github.com%2Frussellhaering%2Fgosaml2

This affects all versions of package github.com/russellhaering/gosaml2. There is a crash on nil-pointer dereference caused by sending malformed XML signatures.

The document mentions #59 which was fixed with #90

Maybe https://ossindex.sonatype.org/vulnerability/CVE-2020-7731?component-type=golang&component-name=github.com%2Frussellhaering%2Fgosaml2 is not up-to-date.

Azure AD works fine

I just checked your demo on Microsoft Azure AD and it works fine to me. The only think I touched is
configuration of ServiceProviderIssuer and IdentityProviderIssuer. I put my example here.

sp := &saml2.SAMLServiceProvider{
	IdentityProviderSSOURL:      metadata.IDPSSODescriptor.SingleSignOnServices[0].Location,
	ServiceProviderIssuer:       "myApp",
	IdentityProviderIssuer:      "https://sts.windows.net/some-guid/",
	AssertionConsumerServiceURL: "https://localhost:8080/api/sso-reply",
	SignAuthnRequests:           true,
	AudienceURI:                 "http://localhost:8080/api/sso",
	IDPCertificateStore:         &certStore,
	SPKeyStore:                  randomKeyStore,
}

Thank you! Hope it might help.

Push a new tag and release

Thank you for your continued support of this package over the years!

This package will show up with a vulnerability because the latest tag v0.6.0 has a dependency on an unpatched version of goxmldsig <v1.1.0.

For anyone curious, there was a patch upstream russellhaering/goxmldsig#48 against GHSA-q547-gmf8-8jr7

To solve this we pinned the latest commit explicitly in our go.mod

github.com/russellhaering/gosaml2 v0.6.1-0.20210916051624-757d23f1bc28

But it'll be nice to avoid special casing this and get a version bump, say v.0.6.1 or v0.7.0. What do you think @russellhaering ?

Multiple assertions with the same key

Howdy,

I noticed that currently assertions are stored as a map[string]string โ€” meaning that two assertions with the same key (i.e. a multi-valued LDAP property) will get overwritten. I thought of two ways to fix this:

  1. Break compatibility, and switch to a map[string][]string, possibly wrapped like a url.Form, so that the common case is simple.
  2. Keep the AssertionInfo map, but add a supplementary list of Assertion objects. (This would also allow some implementations to use the friendly attribute name.)

Thoughts?

Missing signature referencing the top-level element

I have tried to use https://github.com/russellhaering/gosaml2/blob/master/s2example/demo.go to set up an integration test with Okta but I am not making much progress.

After tracing through the example and imported libs I noticed I was getting the following error (via adding my own debug):

>>>> assertionInfo: (*saml2.AssertionInfo)(nil), err: saml2.ErrVerification{Cause:saml2.ErrInvalidValue{Key:"Issuer", Expected:"urn:example:idp", Actual:"http://example.com/saml/acs/example", Reason:""}}

From main.go:

		assertionInfo, err := sp.RetrieveAssertionInfo(req.FormValue("SAMLResponse"))
		fmt.Printf(">>>> assertionInfo: %#v, err: %#v\n", assertionInfo, err)
		if err != nil {
			rw.WriteHeader(http.StatusForbidden)
			return
		}

Diving into this further it leads me to:

File: retrieve_assertion.go
40: 	response, err := sp.ValidateEncodedResponse(encodedResponse)
41: 	if err != nil {
42: 		return nil, ErrVerification{Cause: err}
43: 	}

And:

File: decode_response.go
228: 	var responseSignatureValidated bool
229: 	if !sp.SkipSignatureValidation {
230: 		el, err = sp.validateElementSignature(el)
231: 		fmt.Printf(">>>> el: %#v, err: %#v\n", el, err)
232: 		if err == dsig.ErrMissingSignature {

That prints:

>>>> el: (*etree.Element)(nil), err: &errors.errorString{s:"Missing signature referencing the top-level element"}

Can anyone confirm the Okta IDP integration still works? What could I possibly be doing wrong using the provided example?

AWS SSO problems in auth flow

Hello,

I found your library and have some trouble setting it up to work with the AWS SSO SAML provider.

I followed the s2sample and adjusted some things. First I adjusted the http.Get() call to the metadata of the AWS SSO Portal link of my application. Which I configured like this:
Application start URL: http://localhost:8080/v1/_saml_callback
Application ACS URL: http://localhost:8080/v1/_saml_callback
Application SAML Audience: http://localhost:8080/

I had to create my own tls keypair and configured it for the SPKeyStore field in the SAMLServiceProvider{} struct as dsig.TLSCertKeyStore(keyPair).

As I am new to SAML Im not fully convinced I have set the correct URLs, but as the example application only exposes the /v1/_saml_callback handler, I guess this should be more or less correct.

When I start the application it prints out the sp.BuildAuthURL and if I open this in my browser I will get an error message from the AWS with "Issuer of request does not match our record".

Suitable to this, when I login to the application page in the AWS SSO and activate the configured application to start the process of logging in from the IdP page, I get an 403 not authorized error from the /v1/_saml_callback page.

Any hints what I may be doing wrong, as I suspect the error on my side and not your library.

Marcus

Name ID format not included in assertionInfo

The SAML assertion includes the NameID format along with the NameID. For example, a SAML assertion sent back from the IdP could have:

<saml:NameID
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">
3f7b3dcf-1674-4ecd-92c8-1544f346baf8
</saml:NameID>

Having the NameID format available in AssertionInfo could be useful for service providers if they only accept certain kinds of NameID formats and want to validate based off this field.

Does not work with samltest.id

Setup from the example in README but used samltest.id instead of Okta for the IDP. Get the following message on samltest.id after the redirect to IDP:

Web Login Service - Message Security Error

The request cannot be fulfilled because the message received does not meet the security requirements of the login service...

In the error logs, I see some messages about invalid / unsupported envelope transforms:

2020-11-08 04:32:09,953 - DEBUG [org.opensaml.saml.common.binding.impl.SAMLAddAttributeConsumingServiceHandler:?] - Message Handler:  Selecting default AttributeConsumingService, if any
2020-11-08 04:32:09,953 - DEBUG [org.opensaml.saml.common.binding.impl.SAMLAddAttributeConsumingServiceHandler:?] - Message Handler:  No AttributeConsumingService selected
2020-11-08 04:32:09,954 - DEBUG [net.shibboleth.idp.saml.profile.impl.InitializeRelyingPartyContextFromSAMLPeer:?] - Profile Action InitializeRelyingPartyContextFromSAMLPeer: Attaching RelyingPartyContext based on SAML peer boogie-woogie
2020-11-08 04:32:09,954 - DEBUG [net.shibboleth.idp.profile.interceptor.impl.FilterFlowsByNonBrowserSupport:?] - Profile Action FilterFlowsByNonBrowserSupport: Request does not have non-browser requirement, nothing to do
2020-11-08 04:32:09,955 - DEBUG [org.opensaml.saml.common.binding.security.impl.ReceivedEndpointSecurityHandler:?] - Message Handler:  Checking SAML message intended destination endpoint against receiver endpoint
2020-11-08 04:32:09,955 - DEBUG [org.opensaml.saml.common.binding.security.impl.ReceivedEndpointSecurityHandler:?] - Message Handler:  Intended message destination endpoint: https://samltest.id/idp/profile/SAML2/Redirect/SSO
2020-11-08 04:32:09,955 - DEBUG [org.opensaml.saml.common.binding.security.impl.ReceivedEndpointSecurityHandler:?] - Message Handler:  Actual message receiver endpoint: https://samltest.id/idp/profile/SAML2/Redirect/SSO
2020-11-08 04:32:09,955 - DEBUG [org.opensaml.saml.common.binding.security.impl.ReceivedEndpointSecurityHandler:?] - Message Handler:  SAML message intended destination endpoint matched recipient endpoint
2020-11-08 04:32:09,955 - DEBUG [org.opensaml.saml.common.binding.security.impl.MessageReplaySecurityHandler:?] - Message Handler:  Evaluating message replay for message ID '_14c6baf5-d444-46af-96e6-53d288164010', issue instant '2020-11-08T04:32:09.000Z', entityID 'boogie-woogie'
2020-11-08 04:32:09,955 - DEBUG [org.opensaml.saml.security.impl.SAMLSignatureProfileValidator:?] - Saw Enveloped signature transform
2020-11-08 04:32:09,955 - ERROR [org.opensaml.saml.security.impl.SAMLSignatureProfileValidator:?] - Saw invalid signature transform: http://www.w3.org/2006/12/xml-c14n11
2020-11-08 04:32:09,956 - DEBUG [org.opensaml.saml.common.binding.security.impl.SAMLProtocolMessageXMLSignatureSecurityHandler:?] - Message Handler:  Protocol message signature failed signature pre-validation
org.opensaml.xmlsec.signature.support.SignatureException: Signature contained an invalid transform
	at org.opensaml.saml.security.impl.SAMLSignatureProfileValidator.validateTransforms(SAMLSignatureProfileValidator.java:243)
2020-11-08 04:32:09,956 - WARN [org.opensaml.profile.action.impl.LogEvent:?] - A non-proceed event occurred while processing the request: MessageAuthenticationError
2020-11-08 04:32:09,956 - DEBUG [org.opensaml.saml.common.profile.logic.DefaultLocalErrorPredicate:?] - No SAMLBindingContext or binding URI available, error must be handled locally

Not my area of expertise, so need some guidance here on what's going on.

Support Uncompressed SAML

Azure AD does not support request compression.
All requests are compressed using flate.DefaultCompression.
Please add optional support for specifying no compression.

How to ignore the received public encryption certificate

Hello,

We have a compatibility problem when switching to gosaml2 (from pysaml2) because we don't keep the public encryption certificate. But gosaml2 will fail when decrypting an EncryptedAssertion that contains this certificate as it tries to validate it against the client provided one (which we don't keep): "The EncryptedKey may or may not include X509Data (certificate)", current line

// The EncryptedKey may or may not include X509Data (certificate).
. It fails even if this certificate isn't used afterwards. Can this validation be ignored in certain cases? Like using ValidateEncryptionCert also in this case maybe ?
The second question is security ... Would ignoring this certificate be a security problem ? The only justification I was able to find for this certificate inclusion is "The reason a public key is specified in the SAML response is because the metadata for an identity provider can specify multiple public keys."

Thank you,

samlp:NameIDPolicy Format attribute is written even if unspecified, causing Azure AD problems

The NameIDPolicy element and Format attribute are optional as per SAML spec. However, build_request.go always creates them, even if no value has been specified in SAMLServiceProvider.NameIdFormat. This results in a SAML request to the IdP containing:

<samlp:NameIDPolicy AllowCreate="true" Format="" />

Azure AD appears to have problems with this, replying with an InvalidNameIDPolicy error and saying

Cannot provide requested name identifier with format  for the given subject

(note two spaces between "format" and "for").

I think this is arguably a bug on Azure's part, since the standard says "if no Format value is provided, then the value urn:oasis:names:tc:SAML:1.0:nameid-format:unspecified (see Section 8.3.1) is in effect", and "" isn't a Format value. However, gosaml2's behavior is also a bug, and probably much easier to fix.

There's a PR which attempts to fix this -- #67 -- but I think it would be better to omit only the Format attribute when unspecified, and still allow the IdP to create new IDs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.