core: bump webauthn from 1.11.1 to 2.0.0 (#8134)
* core: bump webauthn from 1.11.1 to 2.0.0 Bumps [webauthn](https://github.com/duo-labs/py_webauthn) from 1.11.1 to 2.0.0. - [Release notes](https://github.com/duo-labs/py_webauthn/releases) - [Changelog](https://github.com/duo-labs/py_webauthn/blob/master/CHANGELOG.md) - [Commits](https://github.com/duo-labs/py_webauthn/compare/v1.11.1...v2.0.0) --- updated-dependencies: - dependency-name: webauthn dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * actually fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
be66ee52cd
commit
f77c2e8254
|
@ -1,4 +1,5 @@
|
||||||
"""Validation stage challenge checking"""
|
"""Validation stage challenge checking"""
|
||||||
|
from json import loads
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
|
@ -10,11 +11,12 @@ from django.utils.translation import gettext_lazy as _
|
||||||
from rest_framework.fields import CharField
|
from rest_framework.fields import CharField
|
||||||
from rest_framework.serializers import ValidationError
|
from rest_framework.serializers import ValidationError
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
from webauthn import options_to_json
|
||||||
from webauthn.authentication.generate_authentication_options import generate_authentication_options
|
from webauthn.authentication.generate_authentication_options import generate_authentication_options
|
||||||
from webauthn.authentication.verify_authentication_response import verify_authentication_response
|
from webauthn.authentication.verify_authentication_response import verify_authentication_response
|
||||||
from webauthn.helpers.base64url_to_bytes import base64url_to_bytes
|
from webauthn.helpers.base64url_to_bytes import base64url_to_bytes
|
||||||
from webauthn.helpers.exceptions import InvalidAuthenticationResponse
|
from webauthn.helpers.exceptions import InvalidAuthenticationResponse
|
||||||
from webauthn.helpers.structs import AuthenticationCredential
|
from webauthn.helpers.structs import UserVerificationRequirement
|
||||||
|
|
||||||
from authentik.core.api.utils import JSONDictField, PassiveSerializer
|
from authentik.core.api.utils import JSONDictField, PassiveSerializer
|
||||||
from authentik.core.models import Application, User
|
from authentik.core.models import Application, User
|
||||||
|
@ -66,12 +68,7 @@ def get_webauthn_challenge_without_user(
|
||||||
)
|
)
|
||||||
request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = authentication_options.challenge
|
request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = authentication_options.challenge
|
||||||
|
|
||||||
return authentication_options.model_dump(
|
return loads(options_to_json(authentication_options))
|
||||||
mode="json",
|
|
||||||
by_alias=True,
|
|
||||||
exclude_unset=False,
|
|
||||||
exclude_none=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_webauthn_challenge(
|
def get_webauthn_challenge(
|
||||||
|
@ -91,17 +88,12 @@ def get_webauthn_challenge(
|
||||||
authentication_options = generate_authentication_options(
|
authentication_options = generate_authentication_options(
|
||||||
rp_id=get_rp_id(request),
|
rp_id=get_rp_id(request),
|
||||||
allow_credentials=allowed_credentials,
|
allow_credentials=allowed_credentials,
|
||||||
user_verification=stage.webauthn_user_verification,
|
user_verification=UserVerificationRequirement(stage.webauthn_user_verification),
|
||||||
)
|
)
|
||||||
|
|
||||||
request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = authentication_options.challenge
|
request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = authentication_options.challenge
|
||||||
|
|
||||||
return authentication_options.model_dump(
|
return loads(options_to_json(authentication_options))
|
||||||
mode="json",
|
|
||||||
by_alias=True,
|
|
||||||
exclude_unset=False,
|
|
||||||
exclude_none=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def select_challenge(request: HttpRequest, device: Device):
|
def select_challenge(request: HttpRequest, device: Device):
|
||||||
|
@ -152,7 +144,7 @@ def validate_challenge_webauthn(data: dict, stage_view: StageView, user: User) -
|
||||||
|
|
||||||
try:
|
try:
|
||||||
authentication_verification = verify_authentication_response(
|
authentication_verification = verify_authentication_response(
|
||||||
credential=AuthenticationCredential.model_validate(data),
|
credential=data,
|
||||||
expected_challenge=challenge,
|
expected_challenge=challenge,
|
||||||
expected_rp_id=get_rp_id(request),
|
expected_rp_id=get_rp_id(request),
|
||||||
expected_origin=get_origin(request),
|
expected_origin=get_origin(request),
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
"""WebAuthn stage"""
|
"""WebAuthn stage"""
|
||||||
|
from json import loads
|
||||||
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.http.request import QueryDict
|
from django.http.request import QueryDict
|
||||||
from rest_framework.fields import CharField
|
from rest_framework.fields import CharField
|
||||||
from rest_framework.serializers import ValidationError
|
from rest_framework.serializers import ValidationError
|
||||||
|
from webauthn import options_to_json
|
||||||
from webauthn.helpers.bytes_to_base64url import bytes_to_base64url
|
from webauthn.helpers.bytes_to_base64url import bytes_to_base64url
|
||||||
from webauthn.helpers.exceptions import InvalidRegistrationResponse
|
from webauthn.helpers.exceptions import InvalidRegistrationResponse
|
||||||
from webauthn.helpers.structs import (
|
from webauthn.helpers.structs import (
|
||||||
AuthenticatorSelectionCriteria,
|
AuthenticatorSelectionCriteria,
|
||||||
PublicKeyCredentialCreationOptions,
|
PublicKeyCredentialCreationOptions,
|
||||||
RegistrationCredential,
|
ResidentKeyRequirement,
|
||||||
|
UserVerificationRequirement,
|
||||||
)
|
)
|
||||||
from webauthn.registration.generate_registration_options import generate_registration_options
|
from webauthn.registration.generate_registration_options import generate_registration_options
|
||||||
from webauthn.registration.verify_registration_response import (
|
from webauthn.registration.verify_registration_response import (
|
||||||
|
@ -53,7 +57,7 @@ class AuthenticatorWebAuthnChallengeResponse(ChallengeResponse):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
registration: VerifiedRegistration = verify_registration_response(
|
registration: VerifiedRegistration = verify_registration_response(
|
||||||
credential=RegistrationCredential.model_validate(response),
|
credential=response,
|
||||||
expected_challenge=challenge,
|
expected_challenge=challenge,
|
||||||
expected_rp_id=get_rp_id(self.request),
|
expected_rp_id=get_rp_id(self.request),
|
||||||
expected_origin=get_origin(self.request),
|
expected_origin=get_origin(self.request),
|
||||||
|
@ -91,12 +95,12 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
|
||||||
registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(
|
registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(
|
||||||
rp_id=get_rp_id(self.request),
|
rp_id=get_rp_id(self.request),
|
||||||
rp_name=self.request.tenant.branding_title,
|
rp_name=self.request.tenant.branding_title,
|
||||||
user_id=user.uid,
|
user_id=user.uid.encode("utf-8"),
|
||||||
user_name=user.username,
|
user_name=user.username,
|
||||||
user_display_name=user.name,
|
user_display_name=user.name,
|
||||||
authenticator_selection=AuthenticatorSelectionCriteria(
|
authenticator_selection=AuthenticatorSelectionCriteria(
|
||||||
resident_key=str(stage.resident_key_requirement),
|
resident_key=ResidentKeyRequirement(str(stage.resident_key_requirement)),
|
||||||
user_verification=str(stage.user_verification),
|
user_verification=UserVerificationRequirement(str(stage.user_verification)),
|
||||||
authenticator_attachment=authenticator_attachment,
|
authenticator_attachment=authenticator_attachment,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -106,12 +110,7 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
|
||||||
return AuthenticatorWebAuthnChallenge(
|
return AuthenticatorWebAuthnChallenge(
|
||||||
data={
|
data={
|
||||||
"type": ChallengeTypes.NATIVE.value,
|
"type": ChallengeTypes.NATIVE.value,
|
||||||
"registration": registration_options.model_dump(
|
"registration": loads(options_to_json(registration_options)),
|
||||||
mode="json",
|
|
||||||
by_alias=True,
|
|
||||||
exclude_unset=False,
|
|
||||||
exclude_none=True,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4153,21 +4153,20 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webauthn"
|
name = "webauthn"
|
||||||
version = "1.11.1"
|
version = "2.0.0"
|
||||||
description = "Pythonic WebAuthn"
|
description = "Pythonic WebAuthn"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
files = [
|
files = [
|
||||||
{file = "webauthn-1.11.1-py3-none-any.whl", hash = "sha256:13592ee71489b571cb6e4a5d8b3c34f7b040cd3539a9d94b6b7d23fa88df5dfb"},
|
{file = "webauthn-2.0.0-py3-none-any.whl", hash = "sha256:644dc68af5caaade06be6a2a2278775e85116e92dd755ad7a49d992d51c82033"},
|
||||||
{file = "webauthn-1.11.1.tar.gz", hash = "sha256:24eda57903897369797f52a377f8c470e7057e79da5525779d0720a9fcc11926"},
|
{file = "webauthn-2.0.0.tar.gz", hash = "sha256:12cc1759da98668b8242badc37c4129df300f89d89f5c183fac80e7b33c41dfd"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
asn1crypto = ">=1.4.0"
|
asn1crypto = ">=1.4.0"
|
||||||
cbor2 = ">=5.4.6"
|
cbor2 = ">=5.4.6"
|
||||||
cryptography = ">=41.0.4"
|
cryptography = ">=41.0.7"
|
||||||
pydantic = ">=1.10.11"
|
pyOpenSSL = ">=23.3.0"
|
||||||
pyOpenSSL = ">=23.2.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "websocket-client"
|
name = "websocket-client"
|
||||||
|
|
Reference in New Issue