def get_challenge(self, *args, **kwargs) -> Challenge: # clear session variables prior to starting a new registration self.request.session.pop("challenge", None) stage: AuthenticateWebAuthnStage = self.executor.current_stage user = self.get_pending_user() # library accepts none so we store null in the database, but if there is a value # set, cast it to string to ensure it's not a django class authenticator_attachment = stage.authenticator_attachment if authenticator_attachment: authenticator_attachment = str(authenticator_attachment) registration_options: PublicKeyCredentialCreationOptions = generate_registration_options( rp_id=get_rp_id(self.request), rp_name=self.request.tenant.branding_title, user_id=user.uid, user_name=user.username, user_display_name=user.name, authenticator_selection=AuthenticatorSelectionCriteria( resident_key=str(stage.resident_key_requirement), user_verification=str(stage.user_verification), authenticator_attachment=authenticator_attachment, ), ) self.request.session["challenge"] = registration_options.challenge return AuthenticatorWebAuthnChallenge( data={ "type": ChallengeTypes.NATIVE.value, "registration": loads(options_to_json(registration_options)), })
def get(self, request, *args, **kwargs): credentials = [] for user_device in request.user.userwebauthn_set.all(): credentials.append(PublicKeyCredentialDescriptor(id=user_device.get_key_handle_bytes())) registration_options = json.loads( options_to_json( generate_registration_options( rp_id=zentral_settings["api"]["fqdn"], rp_name="Zentral", exclude_credentials=credentials, user_id=str(request.user.pk), user_name=request.user.username, ) ) ) request.session["webauthn_challenge"] = registration_options return super().get(request, *args, **kwargs)
def set_challenge(self): credentials = [] appid = None for user_device in self.user.userwebauthn_set.all(): credentials.append( PublicKeyCredentialDescriptor( id=user_device.get_key_handle_bytes())) device_appid = user_device.get_appid() if device_appid: appid = device_appid if credentials: authentication_options = json.loads( options_to_json( generate_authentication_options( rp_id=zentral_settings["api"]["fqdn"], allow_credentials=credentials, ))) if appid: authentication_options["extensions"] = {"appid": appid} challenge = self.session["webauthn_challenge"] = dict( authentication_options) return challenge
def get(self, request): """ :param request: The current request :type request: ~django.http.HttpResponse :return: The mfa challenge as JSON :rtype: ~django.http.JsonResponse """ if "mfa_user_id" not in request.session: return JsonResponse( { "success": False, "error": _("You need to log in first") }, status=403) if request.user.is_authenticated: return JsonResponse({ "success": False, "error": _("You are already logged in.") }) user = get_user_model().objects.get(id=request.session["mfa_user_id"]) webauthn_challenge = generate_authentication_options( rp_id=settings.HOSTNAME, allow_credentials=[ PublicKeyCredentialDescriptor(id=key.key_id) for key in user.mfa_keys.all() ], ) request.session["challenge"] = bytes_to_base64url( webauthn_challenge.challenge) # pylint: disable=http-response-with-content-type-json return HttpResponse(options_to_json(webauthn_challenge), content_type="application/json")
################ # # Examples of using webauthn for registration ceremonies # ################ # Simple Options simple_registration_options = generate_registration_options( rp_id="example.com", rp_name="Example Co", user_id="12345", user_name="bob", ) print("\n[Registration Options - Simple]") print(options_to_json(simple_registration_options)) # Complex Options complex_registration_options = generate_registration_options( rp_id="example.com", rp_name="Example Co", user_id="ABAV6QWPBEY9WOTOA1A4", user_name="lee", user_display_name="Lee", attestation=AttestationConveyancePreference.DIRECT, authenticator_selection=AuthenticatorSelectionCriteria( authenticator_attachment=AuthenticatorAttachment.PLATFORM, resident_key=ResidentKeyRequirement.REQUIRED, ), challenge=b"1234567890", exclude_credentials=[
################ # # Examples of using webauthn for authentication ceremonies # # Authentication responses are representative of WebAuthn credential responses # as they would be encoded for transmission from the browser to the RP as JSON. This # primarily means byte arrays are encoded as Base64URL on the client. # ################ # Simple Options simple_authentication_options = generate_authentication_options( rp_id="example.com") print("\n[Authentication Options - Simple]") print(options_to_json(simple_authentication_options)) # Complex Options complex_authentication_options = generate_authentication_options( rp_id="example.com", challenge=b"1234567890", timeout=12000, allow_credentials=[PublicKeyCredentialDescriptor(id=b"1234567890")], user_verification=UserVerificationRequirement.REQUIRED, ) print("\n[Authentication Options - Complex]") print(options_to_json(complex_authentication_options)) # Authentication Response Verification authentication_verification = verify_authentication_response(