providers/saml: set AuthnContextClassRef based on login event
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> #4070
This commit is contained in:
parent
5019346ab6
commit
1fa9b3a996
|
@ -10,6 +10,7 @@ from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.core.exceptions import PropertyMappingExpressionException
|
from authentik.core.exceptions import PropertyMappingExpressionException
|
||||||
from authentik.events.models import Event, EventAction
|
from authentik.events.models import Event, EventAction
|
||||||
|
from authentik.events.signals import SESSION_LOGIN_EVENT
|
||||||
from authentik.lib.utils.time import timedelta_from_string
|
from authentik.lib.utils.time import timedelta_from_string
|
||||||
from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider
|
from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider
|
||||||
from authentik.providers.saml.processors.request_parser import AuthNRequest
|
from authentik.providers.saml.processors.request_parser import AuthNRequest
|
||||||
|
@ -30,6 +31,7 @@ from authentik.sources.saml.processors.constants import (
|
||||||
SAML_NAME_ID_FORMAT_X509,
|
SAML_NAME_ID_FORMAT_X509,
|
||||||
SIGN_ALGORITHM_TRANSFORM_MAP,
|
SIGN_ALGORITHM_TRANSFORM_MAP,
|
||||||
)
|
)
|
||||||
|
from authentik.stages.password.stage import PLAN_CONTEXT_METHOD, PLAN_CONTEXT_METHOD_ARGS
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
@ -129,9 +131,23 @@ class AssertionProcessor:
|
||||||
auth_n_context_class_ref = SubElement(
|
auth_n_context_class_ref = SubElement(
|
||||||
auth_n_context, f"{{{NS_SAML_ASSERTION}}}AuthnContextClassRef"
|
auth_n_context, f"{{{NS_SAML_ASSERTION}}}AuthnContextClassRef"
|
||||||
)
|
)
|
||||||
|
auth_n_context_class_ref.text = "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"
|
||||||
|
if SESSION_LOGIN_EVENT in self.http_request.session:
|
||||||
|
event: Event = self.http_request.session[SESSION_LOGIN_EVENT]
|
||||||
|
method = event.context.get(PLAN_CONTEXT_METHOD, "")
|
||||||
|
method_args = event.context.get(PLAN_CONTEXT_METHOD_ARGS, {})
|
||||||
|
if method == "password":
|
||||||
auth_n_context_class_ref.text = (
|
auth_n_context_class_ref.text = (
|
||||||
"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
|
"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
|
||||||
)
|
)
|
||||||
|
if "mfa_devices" in method_args:
|
||||||
|
auth_n_context_class_ref.text = (
|
||||||
|
"urn:oasis:names:tc:SAML:2.0:ac:classes:MobileTwoFactorContract"
|
||||||
|
)
|
||||||
|
if method in ["auth_mfa", "auth_webauthn_pwl"]:
|
||||||
|
auth_n_context_class_ref.text = (
|
||||||
|
"urn:oasis:names:tc:SAML:2.0:ac:classes:MobileOneFactorContract"
|
||||||
|
)
|
||||||
return auth_n_statement
|
return auth_n_statement
|
||||||
|
|
||||||
def get_assertion_conditions(self) -> Element:
|
def get_assertion_conditions(self) -> Element:
|
||||||
|
|
|
@ -134,7 +134,7 @@ class AuthenticatorValidationChallengeResponse(ChallengeResponse):
|
||||||
# Here we only check if the any data was sent at all
|
# Here we only check if the any data was sent at all
|
||||||
if "code" not in attrs and "webauthn" not in attrs and "duo" not in attrs:
|
if "code" not in attrs and "webauthn" not in attrs and "duo" not in attrs:
|
||||||
raise ValidationError("Empty response")
|
raise ValidationError("Empty response")
|
||||||
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD, "mfa")
|
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD, "auth_mfa")
|
||||||
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD_ARGS, {})
|
self.stage.executor.plan.context.setdefault(PLAN_CONTEXT_METHOD_ARGS, {})
|
||||||
self.stage.executor.plan.context[PLAN_CONTEXT_METHOD_ARGS].setdefault("mfa_devices", [])
|
self.stage.executor.plan.context[PLAN_CONTEXT_METHOD_ARGS].setdefault("mfa_devices", [])
|
||||||
self.stage.executor.plan.context[PLAN_CONTEXT_METHOD_ARGS]["mfa_devices"].append(
|
self.stage.executor.plan.context[PLAN_CONTEXT_METHOD_ARGS]["mfa_devices"].append(
|
||||||
|
|
|
@ -169,7 +169,7 @@ class AuthenticatorValidateStageDuoTests(FlowTestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.context,
|
event.context,
|
||||||
{
|
{
|
||||||
"auth_method": "mfa",
|
"auth_method": "auth_mfa",
|
||||||
"auth_method_args": {
|
"auth_method_args": {
|
||||||
"mfa_devices": [
|
"mfa_devices": [
|
||||||
{
|
{
|
||||||
|
|
Reference in New Issue