From 607bbcc324e0d0410d0b25fd40358f0d2bd2e9b1 Mon Sep 17 00:00:00 2001 From: James Elliott Date: Tue, 14 Jun 2022 15:17:11 +1000 Subject: [PATCH] fix(handler): oidc two factor handling (#3512) --- internal/authentication/util.go | 15 +++++++++++++++ .../handler_oidc_authorization_consent.go | 15 ++++++++++++--- internal/oidc/client_test.go | 1 + 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 internal/authentication/util.go diff --git a/internal/authentication/util.go b/internal/authentication/util.go new file mode 100644 index 000000000..80d2ec119 --- /dev/null +++ b/internal/authentication/util.go @@ -0,0 +1,15 @@ +package authentication + +// LevelToString returns a string representation of an authentication.Level. +func LevelToString(level Level) string { + switch level { + case NotAuthenticated: + return "not_authenticated" + case OneFactor: + return "one_factor" + case TwoFactor: + return "two_factor" + } + + return "invalid" +} diff --git a/internal/handlers/handler_oidc_authorization_consent.go b/internal/handlers/handler_oidc_authorization_consent.go index eb7579906..a4419d293 100644 --- a/internal/handlers/handler_oidc_authorization_consent.go +++ b/internal/handlers/handler_oidc_authorization_consent.go @@ -8,6 +8,8 @@ import ( "github.com/google/uuid" "github.com/ory/fosite" + "github.com/authelia/authelia/v4/internal/authentication" + "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" @@ -105,7 +107,7 @@ func handleOIDCAuthorizationConsentWithChallengeID(ctx *middlewares.AutheliaCtx, return consent, false } - handleOIDCAuthorizationConsentRedirect(rootURI, client, userSession, rw, r) + handleOIDCAuthorizationConsentRedirect(ctx, rootURI, client, userSession, rw, r, requester) return consent, true } @@ -169,16 +171,23 @@ func handleOIDCAuthorizationConsentGenerate(ctx *middlewares.AutheliaCtx, rootUR return nil, true } - handleOIDCAuthorizationConsentRedirect(rootURI, client, userSession, rw, r) + handleOIDCAuthorizationConsentRedirect(ctx, rootURI, client, userSession, rw, r, requester) return consent, true } -func handleOIDCAuthorizationConsentRedirect(destination string, client *oidc.Client, userSession session.UserSession, rw http.ResponseWriter, r *http.Request) { +func handleOIDCAuthorizationConsentRedirect(ctx *middlewares.AutheliaCtx, destination string, client *oidc.Client, + userSession session.UserSession, rw http.ResponseWriter, r *http.Request, requester fosite.AuthorizeRequester) { if client.IsAuthenticationLevelSufficient(userSession.AuthenticationLevel) { + ctx.Logger.Debugf("Authorization Request with id '%s' on client with id '%s' authentication level '%s' is sufficient for client level '%s'", requester.GetID(), client.GetID(), authentication.LevelToString(userSession.AuthenticationLevel), authorization.LevelToPolicy(client.Policy)) + destination = fmt.Sprintf("%s/consent", destination) + } else { + ctx.Logger.Debugf("Authorization Request with id '%s' on client with id '%s' authentication level '%s' is insufficient for client level '%s'", requester.GetID(), client.GetID(), authentication.LevelToString(userSession.AuthenticationLevel), authorization.LevelToPolicy(client.Policy)) } + ctx.Logger.Debugf("Authorization Request with id '%s' on client with id '%s' is being redirected to '%s'", requester.GetID(), client.GetID(), destination) + http.Redirect(rw, r, destination, http.StatusFound) } diff --git a/internal/oidc/client_test.go b/internal/oidc/client_test.go index e208c082e..aaacd5cdf 100644 --- a/internal/oidc/client_test.go +++ b/internal/oidc/client_test.go @@ -41,6 +41,7 @@ func TestNewClient(t *testing.T) { assert.Equal(t, fosite.ResponseModeFormPost, exampleClient.ResponseModes[1]) assert.Equal(t, fosite.ResponseModeQuery, exampleClient.ResponseModes[2]) assert.Equal(t, fosite.ResponseModeFragment, exampleClient.ResponseModes[3]) + assert.Equal(t, authorization.TwoFactor, exampleClient.Policy) } func TestIsAuthenticationLevelSufficient(t *testing.T) {