revert: "feat(IDP): use single callback endpoint"

This reverts commit e126ccc9aa.

# Which Problems Are Solved

#8295 introduced the possibility to handle idps on a single callback,
but broke current setups.

# How the Problems Are Solved

- Revert the change until a proper solution is found. Revert is needed
as docs were also changed.

# Additional Changes

None.

# Additional Context

- relates to #8295
This commit is contained in:
Livio Spring
2024-07-24 14:29:05 +02:00
committed by GitHub
parent c3f8439a49
commit 8d13247413
24 changed files with 65 additions and 80 deletions

View File

@@ -6,7 +6,6 @@ import (
"strings"
"github.com/crewjam/saml/samlsp"
"github.com/muhlemmer/gu"
"github.com/zitadel/logging"
"github.com/zitadel/oidc/v3/pkg/client/rp"
"github.com/zitadel/oidc/v3/pkg/oidc"
@@ -14,8 +13,8 @@ import (
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/api/authz"
http_utils "github.com/zitadel/zitadel/internal/api/http"
http_mw "github.com/zitadel/zitadel/internal/api/http/middleware"
idp_api "github.com/zitadel/zitadel/internal/api/idp"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
@@ -38,8 +37,6 @@ import (
const (
queryIDPConfigID = "idpConfigID"
tmplExternalNotFoundOption = "externalnotfoundoption"
prefixLoginState = "LOGIN_"
)
type externalIDPData struct {
@@ -101,36 +98,6 @@ type externalRegisterFormData struct {
TermsConfirm bool `schema:"terms-confirm"`
}
// IDPCallbackRedirect checks if the state parameter was set by the login UI
// and redirects the request to the login UI idp callback handlers (GET and POST).
// The function is used in the /idps/callback endpoint to distinguish between requests
// starte in the login UI and IdP intents.
func IDPCallbackRedirect(w http.ResponseWriter, r *http.Request, state string) bool {
state, loginUI := authRequestIDFromState(state)
if !loginUI {
return false
}
callback := EndpointExternalLoginCallback
if r.Method == http.MethodPost {
callback = EndpointExternalLoginCallbackFormPost
}
target := gu.PtrCopy(r.URL)
target.Path = HandlerPrefix + callback
q := target.Query()
q.Set("state", state)
target.RawQuery = q.Encode()
http.Redirect(w, r, target.String(), http.StatusTemporaryRedirect)
return true
}
func stateFromAuthRequest(authRequestID string) string {
return prefixLoginState + authRequestID
}
func authRequestIDFromState(state string) (string, bool) {
return strings.CutPrefix(state, prefixLoginState)
}
// handleExternalLoginStep is called as nextStep
func (l *Login) handleExternalLoginStep(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, selectedIDPID string) {
for _, idp := range authReq.AllowedExternalIDPs {
@@ -220,8 +187,7 @@ func (l *Login) handleIDP(w http.ResponseWriter, r *http.Request, authReq *domai
return
}
params := l.sessionParamsFromAuthRequest(r.Context(), authReq, identityProvider.ID)
state := stateFromAuthRequest(authReq.ID)
session, err := provider.BeginAuth(r.Context(), state, params...)
session, err := provider.BeginAuth(r.Context(), authReq.ID, params...)
if err != nil {
l.renderLogin(w, r, authReq, err)
return
@@ -693,7 +659,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http
data := new(externalNotFoundOptionFormData)
authReq, err := l.ensureAuthRequestAndParseData(r, data)
if err != nil {
l.renderError(w, r, authReq, err)
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, err)
return
}
@@ -995,7 +961,7 @@ func (l *Login) googleProvider(ctx context.Context, identityProvider *query.IDPT
return google.New(
identityProvider.GoogleIDPTemplate.ClientID,
secret,
idp_api.CallbackURL(l.externalSecure)(ctx),
l.baseURL(ctx)+EndpointExternalLoginCallback,
identityProvider.GoogleIDPTemplate.Scopes,
)
}
@@ -1014,7 +980,7 @@ func (l *Login) oidcProvider(ctx context.Context, identityProvider *query.IDPTem
identityProvider.OIDCIDPTemplate.Issuer,
identityProvider.OIDCIDPTemplate.ClientID,
secret,
idp_api.CallbackURL(l.externalSecure)(ctx),
l.baseURL(ctx)+EndpointExternalLoginCallback,
identityProvider.OIDCIDPTemplate.Scopes,
openid.DefaultMapper,
opts...,
@@ -1044,7 +1010,7 @@ func (l *Login) oauthProvider(ctx context.Context, identityProvider *query.IDPTe
AuthURL: identityProvider.OAuthIDPTemplate.AuthorizationEndpoint,
TokenURL: identityProvider.OAuthIDPTemplate.TokenEndpoint,
},
RedirectURL: idp_api.CallbackURL(l.externalSecure)(ctx),
RedirectURL: l.baseURL(ctx) + EndpointExternalLoginCallback,
Scopes: identityProvider.OAuthIDPTemplate.Scopes,
}
return oauth.New(
@@ -1062,7 +1028,6 @@ func (l *Login) samlProvider(ctx context.Context, identityProvider *query.IDPTem
if err != nil {
return nil, err
}
rootURL := idp_api.SAMLRootURL(l.externalSecure)(ctx, identityProvider.ID)
opts := make([]saml.ProviderOpts, 0, 6)
if identityProvider.SAMLIDPTemplate.WithSignedRequest {
opts = append(opts, saml.WithSignedRequest())
@@ -1077,12 +1042,11 @@ func (l *Login) samlProvider(ctx context.Context, identityProvider *query.IDPTem
opts = append(opts, saml.WithTransientMappingAttributeName(identityProvider.SAMLIDPTemplate.TransientMappingAttributeName))
}
opts = append(opts,
saml.WithEntityID(rootURL+"saml/metadata"),
saml.WithEntityID(http_utils.BuildOrigin(authz.GetInstance(ctx).RequestedHost(), l.externalSecure)+"/idps/"+identityProvider.ID+"/saml/metadata"),
saml.WithCustomRequestTracker(
requesttracker.New(
func(ctx context.Context, state, samlRequestID string) error {
func(ctx context.Context, authRequestID, samlRequestID string) error {
useragent, _ := http_mw.UserAgentIDFromCtx(ctx)
authRequestID, _ := authRequestIDFromState(state)
return l.authRepo.SaveSAMLRequestID(ctx, authRequestID, samlRequestID, useragent)
},
func(ctx context.Context, authRequestID string) (*samlsp.TrackedRequest, error) {
@@ -1100,7 +1064,7 @@ func (l *Login) samlProvider(ctx context.Context, identityProvider *query.IDPTem
))
return saml.New(
identityProvider.Name,
rootURL,
l.baseURL(ctx)+EndpointExternalLogin+"/",
identityProvider.SAMLIDPTemplate.Metadata,
identityProvider.SAMLIDPTemplate.Certificate,
key,
@@ -1124,7 +1088,7 @@ func (l *Login) azureProvider(ctx context.Context, identityProvider *query.IDPTe
identityProvider.Name,
identityProvider.AzureADIDPTemplate.ClientID,
secret,
idp_api.CallbackURL(l.externalSecure)(ctx),
l.baseURL(ctx)+EndpointExternalLoginCallback,
identityProvider.AzureADIDPTemplate.Scopes,
opts...,
)
@@ -1138,7 +1102,7 @@ func (l *Login) githubProvider(ctx context.Context, identityProvider *query.IDPT
return github.New(
identityProvider.GitHubIDPTemplate.ClientID,
secret,
idp_api.CallbackURL(l.externalSecure)(ctx),
l.baseURL(ctx)+EndpointExternalLoginCallback,
identityProvider.GitHubIDPTemplate.Scopes,
)
}
@@ -1152,7 +1116,7 @@ func (l *Login) githubEnterpriseProvider(ctx context.Context, identityProvider *
identityProvider.Name,
identityProvider.GitHubIDPTemplate.ClientID,
secret,
idp_api.CallbackURL(l.externalSecure)(ctx),
l.baseURL(ctx)+EndpointExternalLoginCallback,
identityProvider.GitHubEnterpriseIDPTemplate.AuthorizationEndpoint,
identityProvider.GitHubEnterpriseIDPTemplate.TokenEndpoint,
identityProvider.GitHubEnterpriseIDPTemplate.UserEndpoint,
@@ -1168,7 +1132,7 @@ func (l *Login) gitlabProvider(ctx context.Context, identityProvider *query.IDPT
return gitlab.New(
identityProvider.GitLabIDPTemplate.ClientID,
secret,
idp_api.CallbackURL(l.externalSecure)(ctx),
l.baseURL(ctx)+EndpointExternalLoginCallback,
identityProvider.GitLabIDPTemplate.Scopes,
)
}
@@ -1183,7 +1147,7 @@ func (l *Login) gitlabSelfHostedProvider(ctx context.Context, identityProvider *
identityProvider.GitLabSelfHostedIDPTemplate.Issuer,
identityProvider.GitLabSelfHostedIDPTemplate.ClientID,
secret,
idp_api.CallbackURL(l.externalSecure)(ctx),
l.baseURL(ctx)+EndpointExternalLoginCallback,
identityProvider.GitLabSelfHostedIDPTemplate.Scopes,
)
}
@@ -1197,7 +1161,7 @@ func (l *Login) appleProvider(ctx context.Context, identityProvider *query.IDPTe
identityProvider.AppleIDPTemplate.ClientID,
identityProvider.AppleIDPTemplate.TeamID,
identityProvider.AppleIDPTemplate.KeyID,
idp_api.CallbackURL(l.externalSecure)(ctx),
l.baseURL(ctx)+EndpointExternalLoginCallbackFormPost,
privateKey,
identityProvider.AppleIDPTemplate.Scopes,
)