summaryrefslogtreecommitdiff
path: root/internal/middlewares/require_auth.go
diff options
context:
space:
mode:
authorJames Elliott <james-d-elliott@users.noreply.github.com>2025-02-23 16:08:49 +1100
committerGitHub <noreply@github.com>2025-02-23 16:08:49 +1100
commit197b45521f5e3799d0b9ef1ec0000d4f83abdee9 (patch)
tree065752a305c6edccaca3d72dfe45868029df8c54 /internal/middlewares/require_auth.go
parent8a5e96a342d28c00b7dcaa72d16f39ddfcdaec74 (diff)
feat(webauthn): passkeys (#7942)
Add support for passkeys, granular attachment modality, granular authenticator selection, and authenticator filtering which is commonly used in an enterprise environment. This also adds metadata verification elements utilizing the MDS3 to the project, including saving attestation statements, verification of attestation statements, etc. This also makes a significant change to the authentication level logic to purely use RFC8176 authentication method references to ensure the future-proof nature of the implementation. This change paves the way for the future of Authelia ensuring we can add custom policies in the future to allow administrators to very deliberately decide what authentication methods are sufficient for a given resource as well as the ability to clearly communicate these authentication methods to third parties via OpenID Connect 1.0 and SAML 2.0. It should be noted that at the time of this commit Passkey authentication is considered a single factor and we will at a later stage add the customizable policies described here to handle other use cases, though we've included a flag that considers properly implemented passkeys as if they were MFA. Closes #2827, Closes #2761 Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
Diffstat (limited to 'internal/middlewares/require_auth.go')
-rw-r--r--internal/middlewares/require_auth.go10
1 files changed, 6 insertions, 4 deletions
diff --git a/internal/middlewares/require_auth.go b/internal/middlewares/require_auth.go
index 5f1c0b590..316c0b1b2 100644
--- a/internal/middlewares/require_auth.go
+++ b/internal/middlewares/require_auth.go
@@ -11,7 +11,7 @@ import (
// Require1FA check if user has enough permissions to execute the next handler.
func Require1FA(next RequestHandler) RequestHandler {
return func(ctx *AutheliaCtx) {
- if s, err := ctx.GetSession(); err != nil || s.AuthenticationLevel < authentication.OneFactor {
+ if s, err := ctx.GetSession(); err != nil || s.AuthenticationLevel(ctx.Configuration.WebAuthn.EnablePasskey2FA) < authentication.OneFactor {
ctx.ReplyForbidden()
return
}
@@ -38,7 +38,7 @@ func RequireElevated(next RequestHandler) RequestHandler {
return
}
- if userSession.AuthenticationLevel < authentication.OneFactor {
+ if userSession.AuthenticationLevel(ctx.Configuration.WebAuthn.EnablePasskey2FA) < authentication.OneFactor {
ctx.Logger.Warn("An anonymous user attempted to access an elevated protected endpoint.")
if err = ctx.ReplyJSON(OKResponse{Status: "KO", Data: ElevatedForbiddenResponse{FirstFactor: true}}, fasthttp.StatusForbidden); err != nil {
@@ -59,13 +59,15 @@ func RequireElevated(next RequestHandler) RequestHandler {
func handleRequireElevatedShouldDoNext(ctx *AutheliaCtx, userSession *session.UserSession) (doNext bool) {
var err error
- if ctx.Configuration.IdentityValidation.ElevatedSession.SkipSecondFactor && userSession.AuthenticationLevel >= authentication.TwoFactor {
+ level := userSession.AuthenticationLevel(ctx.Configuration.WebAuthn.EnablePasskey2FA)
+
+ if ctx.Configuration.IdentityValidation.ElevatedSession.SkipSecondFactor && level >= authentication.TwoFactor {
ctx.Logger.WithFields(map[string]any{"user": userSession.Username}).Trace("The user session elevation was not checked as the user has performed second factor authentication and the policy to skip this is enabled.")
return true
}
- if ctx.Configuration.IdentityValidation.ElevatedSession.RequireSecondFactor && userSession.AuthenticationLevel < authentication.TwoFactor {
+ if ctx.Configuration.IdentityValidation.ElevatedSession.RequireSecondFactor && level < authentication.TwoFactor {
var info model.UserInfo
if info, err = ctx.Providers.StorageProvider.LoadUserInfo(ctx, userSession.Username); err != nil {