mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-09 17:03:40 +00:00
fix(saml): parse xsd:duration format correctly (#9098)
# Which Problems Are Solved
SAML IdPs exposing an `EntitiesDescriptor` using an `xsd:duration` time
format for the `cacheDuration` property (e.g. `PT5H`) failed parsing.
# How the Problems Are Solved
Handle the unmarshalling for `EntitiesDescriptor` specifically.
[crewjam/saml](bbccb7933d/metadata.go (L88-L103)
)
already did this for `EntitiyDescriptor` the same way.
# Additional Changes
None
# Additional Context
- reported by a customer
- needs to be backported to current cloud version (2.66.x)
This commit is contained in:
parent
ab6c4331df
commit
bcf416d4cf
@ -126,7 +126,7 @@ func ParseMetadata(metadata []byte) (*saml.EntityDescriptor, error) {
|
|||||||
if _, err := reader.Seek(0, io.SeekStart); err != nil {
|
if _, err := reader.Seek(0, io.SeekStart); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
entities := &saml.EntitiesDescriptor{}
|
entities := &EntitiesDescriptor{}
|
||||||
if err := decoder.Decode(entities); err != nil {
|
if err := decoder.Decode(entities); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -253,3 +253,26 @@ func nameIDFormatFromDomain(format domain.SAMLNameIDFormat) saml.NameIDFormat {
|
|||||||
return saml.UnspecifiedNameIDFormat
|
return saml.UnspecifiedNameIDFormat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EntitiesDescriptor is a workaround until we eventually fork the crewjam/saml library, since maintenance on that repo seems to have stopped.
|
||||||
|
// This is to be able to handle xsd:duration format using the UnmarshalXML method.
|
||||||
|
// crewjam/saml only implements the xsd:dateTime format for EntityDescriptor, but not EntitiesDescriptor.
|
||||||
|
type EntitiesDescriptor saml.EntitiesDescriptor
|
||||||
|
|
||||||
|
// UnmarshalXML implements xml.Unmarshaler
|
||||||
|
func (m *EntitiesDescriptor) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||||
|
type Alias EntitiesDescriptor
|
||||||
|
aux := &struct {
|
||||||
|
ValidUntil *saml.RelaxedTime `xml:"validUntil,attr,omitempty"`
|
||||||
|
CacheDuration *saml.Duration `xml:"cacheDuration,attr,omitempty"`
|
||||||
|
*Alias
|
||||||
|
}{
|
||||||
|
Alias: (*Alias)(m),
|
||||||
|
}
|
||||||
|
if err := d.DecodeElement(aux, &start); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m.ValidUntil = (*time.Time)(aux.ValidUntil)
|
||||||
|
m.CacheDuration = (*time.Duration)(aux.CacheDuration)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ package saml
|
|||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/crewjam/saml"
|
"github.com/crewjam/saml"
|
||||||
"github.com/crewjam/saml/samlsp"
|
"github.com/crewjam/saml/samlsp"
|
||||||
@ -271,6 +272,31 @@ func TestParseMetadata(t *testing.T) {
|
|||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"valid entities using xsd duration descriptor",
|
||||||
|
args{
|
||||||
|
metadata: []byte(`<?xml version="1.0" encoding="UTF-8"?><EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" cacheDuration="PT5H"><EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://localhost:8000/metadata" cacheDuration="PT5H"><IDPSSODescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"><SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8000/sso"></SingleSignOnService></IDPSSODescriptor></EntityDescriptor></EntitiesDescriptor>`),
|
||||||
|
},
|
||||||
|
&saml.EntityDescriptor{
|
||||||
|
EntityID: "http://localhost:8000/metadata",
|
||||||
|
CacheDuration: 5 * time.Hour,
|
||||||
|
IDPSSODescriptors: []saml.IDPSSODescriptor{
|
||||||
|
{
|
||||||
|
XMLName: xml.Name{
|
||||||
|
Space: "urn:oasis:names:tc:SAML:2.0:metadata",
|
||||||
|
Local: "IDPSSODescriptor",
|
||||||
|
},
|
||||||
|
SingleSignOnServices: []saml.Endpoint{
|
||||||
|
{
|
||||||
|
Binding: saml.HTTPRedirectBinding,
|
||||||
|
Location: "http://localhost:8000/sso",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user