mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 08:07:32 +00:00
fix(saml): provide option to get internal as default ACS (#8888)
# Which Problems Are Solved
Some SAML IdPs including Google only allow to configure a single
AssertionConsumerService URL.
Since the current metadata provides multiple and the hosted login UI is
not published as neither the first nor with `isDefault=true`, those IdPs
take another and then return an error on sign in.
# How the Problems Are Solved
Allow to reorder the ACS URLs using a query parameter
(`internalUI=true`) when retrieving the metadata endpoint.
This will list the `ui/login/login/externalidp/saml/acs` first and also
set the `isDefault=true`.
# Additional Changes
None
# Additional Context
Reported by a customer
(cherry picked from commit 374b9a7f66
)
This commit is contained in:
@@ -8,9 +8,11 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/crewjam/saml"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/muhlemmer/gu"
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
http_utils "github.com/zitadel/zitadel/internal/api/http"
|
||||
@@ -49,6 +51,7 @@ const (
|
||||
paramError = "error"
|
||||
paramErrorDescription = "error_description"
|
||||
varIDPID = "idpid"
|
||||
paramInternalUI = "internalUI"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
@@ -187,21 +190,8 @@ func (h *Handler) handleMetadata(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
metadata := sp.ServiceProvider.Metadata()
|
||||
|
||||
for i, spDesc := range metadata.SPSSODescriptors {
|
||||
spDesc.AssertionConsumerServices = append(
|
||||
spDesc.AssertionConsumerServices,
|
||||
saml.IndexedEndpoint{
|
||||
Binding: saml.HTTPPostBinding,
|
||||
Location: h.loginSAMLRootURL(ctx),
|
||||
Index: len(spDesc.AssertionConsumerServices) + 1,
|
||||
}, saml.IndexedEndpoint{
|
||||
Binding: saml.HTTPArtifactBinding,
|
||||
Location: h.loginSAMLRootURL(ctx),
|
||||
Index: len(spDesc.AssertionConsumerServices) + 2,
|
||||
},
|
||||
)
|
||||
metadata.SPSSODescriptors[i] = spDesc
|
||||
}
|
||||
internalUI, _ := strconv.ParseBool(r.URL.Query().Get(paramInternalUI))
|
||||
h.assertionConsumerServices(ctx, metadata, internalUI)
|
||||
|
||||
buf, _ := xml.MarshalIndent(metadata, "", " ")
|
||||
w.Header().Set("Content-Type", "application/samlmetadata+xml")
|
||||
@@ -212,6 +202,48 @@ func (h *Handler) handleMetadata(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) assertionConsumerServices(ctx context.Context, metadata *saml.EntityDescriptor, internalUI bool) {
|
||||
if !internalUI {
|
||||
for i, spDesc := range metadata.SPSSODescriptors {
|
||||
spDesc.AssertionConsumerServices = append(
|
||||
spDesc.AssertionConsumerServices,
|
||||
saml.IndexedEndpoint{
|
||||
Binding: saml.HTTPPostBinding,
|
||||
Location: h.loginSAMLRootURL(ctx),
|
||||
Index: len(spDesc.AssertionConsumerServices) + 1,
|
||||
}, saml.IndexedEndpoint{
|
||||
Binding: saml.HTTPArtifactBinding,
|
||||
Location: h.loginSAMLRootURL(ctx),
|
||||
Index: len(spDesc.AssertionConsumerServices) + 2,
|
||||
},
|
||||
)
|
||||
metadata.SPSSODescriptors[i] = spDesc
|
||||
}
|
||||
return
|
||||
}
|
||||
for i, spDesc := range metadata.SPSSODescriptors {
|
||||
acs := make([]saml.IndexedEndpoint, 0, len(spDesc.AssertionConsumerServices)+2)
|
||||
acs = append(acs,
|
||||
saml.IndexedEndpoint{
|
||||
Binding: saml.HTTPPostBinding,
|
||||
Location: h.loginSAMLRootURL(ctx),
|
||||
Index: 0,
|
||||
IsDefault: gu.Ptr(true),
|
||||
},
|
||||
saml.IndexedEndpoint{
|
||||
Binding: saml.HTTPArtifactBinding,
|
||||
Location: h.loginSAMLRootURL(ctx),
|
||||
Index: 1,
|
||||
})
|
||||
for i := 0; i < len(spDesc.AssertionConsumerServices); i++ {
|
||||
spDesc.AssertionConsumerServices[i].Index = 2 + i
|
||||
acs = append(acs, spDesc.AssertionConsumerServices[i])
|
||||
}
|
||||
spDesc.AssertionConsumerServices = acs
|
||||
metadata.SPSSODescriptors[i] = spDesc
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) handleACS(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
data := parseSAMLRequest(r)
|
||||
|
Reference in New Issue
Block a user