fix(oidc): pre-conf consent skipped entirely for anon users (#3250)
This fixes an issue where pre-configured consent is entirely skipped if the process was initiated via an anonymous user.pull/3290/head
parent
556a115c83
commit
1db00717ee
|
@ -101,8 +101,6 @@ func OpenIDConnectAuthorizationGET(ctx *middlewares.AutheliaCtx, rw http.Respons
|
|||
|
||||
ctx.Logger.Tracef("Authorization Request with id '%s' on client with id '%s' creating session for Authorization Response for subject '%s' with username '%s' with claims: %+v",
|
||||
requester.GetID(), oidcSession.ClientID, oidcSession.Subject, oidcSession.Username, oidcSession.Claims)
|
||||
ctx.Logger.Tracef("Authorization Request with id '%s' on client with id '%s' creating session for Authorization Response for subject '%s' with username '%s' with headers: %+v",
|
||||
requester.GetID(), oidcSession.ClientID, oidcSession.Subject, oidcSession.Username, oidcSession.Headers)
|
||||
|
||||
if responder, err = ctx.Providers.OpenIDConnect.Fosite.NewAuthorizeResponse(ctx, requester, oidcSession); err != nil {
|
||||
rfc := fosite.ErrorToRFC6749Error(err)
|
||||
|
|
|
@ -117,9 +117,9 @@ func handleOIDCAuthorizationConsentOrGenerate(ctx *middlewares.AutheliaCtx, root
|
|||
err error
|
||||
)
|
||||
|
||||
scopes, audience := getExpectedScopesAndAudience(requester)
|
||||
scopes, audience := getOIDCExpectedScopesAndAudienceFromRequest(requester)
|
||||
|
||||
if consent, err = getOIDCPreconfiguredConsent(ctx, client.GetID(), subject.UUID, scopes, audience); err != nil {
|
||||
if consent, err = getOIDCPreConfiguredConsent(ctx, client.GetID(), subject.UUID, scopes, audience); err != nil {
|
||||
ctx.Logger.Errorf("Authorization Request with id '%s' on client with id '%s' had error looking up pre-configured consent sessions: %+v", requester.GetID(), requester.GetClient().GetID(), err)
|
||||
|
||||
ctx.Providers.OpenIDConnect.Fosite.WriteAuthorizeError(rw, requester, fosite.ErrServerError.WithHint("Could not lookup the consent session."))
|
||||
|
@ -182,16 +182,32 @@ func handleOIDCAuthorizationConsentRedirect(destination string, client *oidc.Cli
|
|||
http.Redirect(rw, r, destination, http.StatusFound)
|
||||
}
|
||||
|
||||
func getExpectedScopesAndAudience(requester fosite.Requester) (scopes, audience []string) {
|
||||
audience = requester.GetRequestedAudience()
|
||||
if !utils.IsStringInSlice(requester.GetClient().GetID(), audience) {
|
||||
audience = append(audience, requester.GetClient().GetID())
|
||||
}
|
||||
|
||||
return requester.GetRequestedScopes(), audience
|
||||
func getOIDCExpectedScopesAndAudienceFromRequest(requester fosite.Requester) (scopes, audience []string) {
|
||||
return getOIDCExpectedScopesAndAudience(requester.GetClient().GetID(), requester.GetRequestedScopes(), requester.GetRequestedAudience())
|
||||
}
|
||||
|
||||
func getOIDCPreconfiguredConsent(ctx *middlewares.AutheliaCtx, clientID string, subject uuid.UUID, scopes, audience []string) (consent *model.OAuth2ConsentSession, err error) {
|
||||
func getOIDCExpectedScopesAndAudience(clientID string, scopes, audience []string) (expectedScopes, expectedAudience []string) {
|
||||
if !utils.IsStringInSlice(clientID, audience) {
|
||||
audience = append(audience, clientID)
|
||||
}
|
||||
|
||||
return scopes, audience
|
||||
}
|
||||
|
||||
func getOIDCPreConfiguredConsentFromClientAndConsent(ctx *middlewares.AutheliaCtx, client fosite.Client, consent *model.OAuth2ConsentSession) (preConfigConsent *model.OAuth2ConsentSession, err error) {
|
||||
if consent == nil || !consent.Subject.Valid {
|
||||
return nil, fmt.Errorf("invalid consent provided for pre-configured consent lookup")
|
||||
}
|
||||
|
||||
scopes, audience := getOIDCExpectedScopesAndAudience(client.GetID(), consent.RequestedScopes, consent.RequestedAudience)
|
||||
|
||||
// We can skip this error as it's handled at the authorization endpoint.
|
||||
preConfigConsent, _ = getOIDCPreConfiguredConsent(ctx, client.GetID(), consent.Subject.UUID, scopes, audience)
|
||||
|
||||
return preConfigConsent, nil
|
||||
}
|
||||
|
||||
func getOIDCPreConfiguredConsent(ctx *middlewares.AutheliaCtx, clientID string, subject uuid.UUID, scopes, audience []string) (consent *model.OAuth2ConsentSession, err error) {
|
||||
var (
|
||||
rows *storage.ConsentSessionRows
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/authelia/authelia/v4/internal/authorization"
|
||||
"github.com/authelia/authelia/v4/internal/middlewares"
|
||||
"github.com/authelia/authelia/v4/internal/model"
|
||||
"github.com/authelia/authelia/v4/internal/oidc"
|
||||
"github.com/authelia/authelia/v4/internal/utils"
|
||||
)
|
||||
|
@ -59,15 +60,49 @@ func handleOIDCWorkflowResponse(ctx *middlewares.AutheliaCtx) {
|
|||
return
|
||||
}
|
||||
|
||||
if userSession.ConsentChallengeID != nil {
|
||||
if consent.Subject.UUID, err = ctx.Providers.OpenIDConnect.Store.GetSubject(ctx, client.GetSectorIdentifier(), userSession.Username); err != nil {
|
||||
ctx.Logger.Errorf("Unable to find subject for the consent session: %v", err)
|
||||
|
||||
respondUnauthorized(ctx, messageOperationFailed)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
consent.Subject.Valid = true
|
||||
|
||||
var preConsent *model.OAuth2ConsentSession
|
||||
|
||||
if preConsent, err = getOIDCPreConfiguredConsentFromClientAndConsent(ctx, client, consent); err != nil {
|
||||
ctx.Logger.Errorf("Unable to lookup pre-configured consent for the consent session: %v", err)
|
||||
|
||||
respondUnauthorized(ctx, messageOperationFailed)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if userSession.ConsentChallengeID != nil && preConsent == nil {
|
||||
if err = ctx.SetJSONBody(redirectResponse{Redirect: fmt.Sprintf("%s/consent", externalRootURL)}); err != nil {
|
||||
ctx.Logger.Errorf("Unable to set default redirection URL in body: %s", err)
|
||||
}
|
||||
} else {
|
||||
if err = ctx.SetJSONBody(redirectResponse{Redirect: fmt.Sprintf("%s%s?%s", externalRootURL, oidc.AuthorizationPath, consent.Form)}); err != nil {
|
||||
ctx.Logger.Errorf("Unable to set default redirection URL in body: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if userSession.ConsentChallengeID != nil {
|
||||
userSession.ConsentChallengeID = nil
|
||||
|
||||
if err = ctx.SaveSession(userSession); err != nil {
|
||||
ctx.Logger.Errorf("Unable to update user session: %v", err)
|
||||
|
||||
respondUnauthorized(ctx, messageOperationFailed)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = ctx.SetJSONBody(redirectResponse{Redirect: fmt.Sprintf("%s%s?%s", externalRootURL, oidc.AuthorizationPath, consent.Form)}); err != nil {
|
||||
ctx.Logger.Errorf("Unable to set default redirection URL in body: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle1FAResponse handle the redirection upon 1FA authentication.
|
||||
|
|
Loading…
Reference in New Issue