mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:27:42 +00:00
feat(saml): allow setting nameid-format and alternative mapping for transient format (#7979)
# Which Problems Are Solved ZITADEL currently always uses `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent` in SAML requests, relying on the IdP to respect that flag and always return a peristent nameid in order to be able to map the external user with an existing user (idp link) in ZITADEL. In case the IdP however returns a `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` (transient) nameid, the attribute will differ between each request and it will not be possible to match existing users. # How the Problems Are Solved This PR adds the following two options on SAML IdP: - **nameIDFormat**: allows to set the nameid-format used in the SAML Request - **transientMappingAttributeName**: allows to set an attribute name, which will be used instead of the nameid itself in case the returned nameid-format is transient # Additional Changes To reduce impact on current installations, the `idp_templates6_saml` table is altered with the two added columns by a setup job. New installations will automatically get the table with the two columns directly. All idp unit tests are updated to use `expectEventstore` instead of the deprecated `eventstoreExpect`. # Additional Context Closes #7483 Closes #7743 --------- Co-authored-by: peintnermax <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
This commit is contained in:
@@ -155,12 +155,14 @@ type AppleIDPTemplate struct {
|
||||
}
|
||||
|
||||
type SAMLIDPTemplate struct {
|
||||
IDPID string
|
||||
Metadata []byte
|
||||
Key *crypto.CryptoValue
|
||||
Certificate []byte
|
||||
Binding string
|
||||
WithSignedRequest bool
|
||||
IDPID string
|
||||
Metadata []byte
|
||||
Key *crypto.CryptoValue
|
||||
Certificate []byte
|
||||
Binding string
|
||||
WithSignedRequest bool
|
||||
NameIDFormat sql.Null[domain.SAMLNameIDFormat]
|
||||
TransientMappingAttributeName string
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -700,6 +702,14 @@ var (
|
||||
name: projection.SAMLWithSignedRequestCol,
|
||||
table: samlIdpTemplateTable,
|
||||
}
|
||||
SAMLNameIDFormatCol = Column{
|
||||
name: projection.SAMLNameIDFormatCol,
|
||||
table: samlIdpTemplateTable,
|
||||
}
|
||||
SAMLTransientMappingAttributeNameCol = Column{
|
||||
name: projection.SAMLTransientMappingAttributeName,
|
||||
table: samlIdpTemplateTable,
|
||||
}
|
||||
)
|
||||
|
||||
// IDPTemplateByID searches for the requested id
|
||||
@@ -883,6 +893,8 @@ func prepareIDPTemplateByIDQuery(ctx context.Context, db prepareDatabase) (sq.Se
|
||||
SAMLCertificateCol.identifier(),
|
||||
SAMLBindingCol.identifier(),
|
||||
SAMLWithSignedRequestCol.identifier(),
|
||||
SAMLNameIDFormatCol.identifier(),
|
||||
SAMLTransientMappingAttributeNameCol.identifier(),
|
||||
// ldap
|
||||
LDAPIDCol.identifier(),
|
||||
LDAPServersCol.identifier(),
|
||||
@@ -997,6 +1009,8 @@ func prepareIDPTemplateByIDQuery(ctx context.Context, db prepareDatabase) (sq.Se
|
||||
var samlCertificate []byte
|
||||
samlBinding := sql.NullString{}
|
||||
samlWithSignedRequest := sql.NullBool{}
|
||||
samlNameIDFormat := sql.Null[domain.SAMLNameIDFormat]{}
|
||||
samlTransientMappingAttributeName := sql.NullString{}
|
||||
|
||||
ldapID := sql.NullString{}
|
||||
ldapServers := database.TextArray[string]{}
|
||||
@@ -1109,6 +1123,8 @@ func prepareIDPTemplateByIDQuery(ctx context.Context, db prepareDatabase) (sq.Se
|
||||
&samlCertificate,
|
||||
&samlBinding,
|
||||
&samlWithSignedRequest,
|
||||
&samlNameIDFormat,
|
||||
&samlTransientMappingAttributeName,
|
||||
// ldap
|
||||
&ldapID,
|
||||
&ldapServers,
|
||||
@@ -1237,12 +1253,14 @@ func prepareIDPTemplateByIDQuery(ctx context.Context, db prepareDatabase) (sq.Se
|
||||
}
|
||||
if samlID.Valid {
|
||||
idpTemplate.SAMLIDPTemplate = &SAMLIDPTemplate{
|
||||
IDPID: samlID.String,
|
||||
Metadata: samlMetadata,
|
||||
Key: samlKey,
|
||||
Certificate: samlCertificate,
|
||||
Binding: samlBinding.String,
|
||||
WithSignedRequest: samlWithSignedRequest.Bool,
|
||||
IDPID: samlID.String,
|
||||
Metadata: samlMetadata,
|
||||
Key: samlKey,
|
||||
Certificate: samlCertificate,
|
||||
Binding: samlBinding.String,
|
||||
WithSignedRequest: samlWithSignedRequest.Bool,
|
||||
NameIDFormat: samlNameIDFormat,
|
||||
TransientMappingAttributeName: samlTransientMappingAttributeName.String,
|
||||
}
|
||||
}
|
||||
if ldapID.Valid {
|
||||
@@ -1370,6 +1388,8 @@ func prepareIDPTemplatesQuery(ctx context.Context, db prepareDatabase) (sq.Selec
|
||||
SAMLCertificateCol.identifier(),
|
||||
SAMLBindingCol.identifier(),
|
||||
SAMLWithSignedRequestCol.identifier(),
|
||||
SAMLNameIDFormatCol.identifier(),
|
||||
SAMLTransientMappingAttributeNameCol.identifier(),
|
||||
// ldap
|
||||
LDAPIDCol.identifier(),
|
||||
LDAPServersCol.identifier(),
|
||||
@@ -1489,6 +1509,8 @@ func prepareIDPTemplatesQuery(ctx context.Context, db prepareDatabase) (sq.Selec
|
||||
var samlCertificate []byte
|
||||
samlBinding := sql.NullString{}
|
||||
samlWithSignedRequest := sql.NullBool{}
|
||||
samlNameIDFormat := sql.Null[domain.SAMLNameIDFormat]{}
|
||||
samlTransientMappingAttributeName := sql.NullString{}
|
||||
|
||||
ldapID := sql.NullString{}
|
||||
ldapServers := database.TextArray[string]{}
|
||||
@@ -1601,6 +1623,8 @@ func prepareIDPTemplatesQuery(ctx context.Context, db prepareDatabase) (sq.Selec
|
||||
&samlCertificate,
|
||||
&samlBinding,
|
||||
&samlWithSignedRequest,
|
||||
&samlNameIDFormat,
|
||||
&samlTransientMappingAttributeName,
|
||||
// ldap
|
||||
&ldapID,
|
||||
&ldapServers,
|
||||
@@ -1728,12 +1752,14 @@ func prepareIDPTemplatesQuery(ctx context.Context, db prepareDatabase) (sq.Selec
|
||||
}
|
||||
if samlID.Valid {
|
||||
idpTemplate.SAMLIDPTemplate = &SAMLIDPTemplate{
|
||||
IDPID: samlID.String,
|
||||
Metadata: samlMetadata,
|
||||
Key: samlKey,
|
||||
Certificate: samlCertificate,
|
||||
Binding: samlBinding.String,
|
||||
WithSignedRequest: samlWithSignedRequest.Bool,
|
||||
IDPID: samlID.String,
|
||||
Metadata: samlMetadata,
|
||||
Key: samlKey,
|
||||
Certificate: samlCertificate,
|
||||
Binding: samlBinding.String,
|
||||
WithSignedRequest: samlWithSignedRequest.Bool,
|
||||
NameIDFormat: samlNameIDFormat,
|
||||
TransientMappingAttributeName: samlTransientMappingAttributeName.String,
|
||||
}
|
||||
}
|
||||
if ldapID.Valid {
|
||||
|
Reference in New Issue
Block a user