1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/webauthn/content/browser/internal_authenticator_impl.h"
#include <string>
#include <utility>
#include "content/public/browser/authenticator_common.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "url/origin.h"
namespace content {
InternalAuthenticatorImpl::InternalAuthenticatorImpl(
RenderFrameHost* render_frame_host)
: WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)),
effective_origin_(render_frame_host->GetLastCommittedOrigin()),
authenticator_common_(AuthenticatorCommon::Create(render_frame_host)) {
// Disabling WebAuthn modal dialogs to avoid conflict with Autofill's own
// modal dialogs. Since WebAuthn is designed for websites, rather than browser
// components, the UI can be confusing for users in the case for Autofill.
// Autofill only ever uses platform authenticators and can take place
// on any webpage.
authenticator_common_->DisableUI();
// WebAuthn policy is to disallow use on pages with "Not secure" or "None" TLS
// connection status. However, internal clients such as autofill may be called
// from these pages (e.g. on chrome://settings/payments).
authenticator_common_->DisableTLSCheck();
}
InternalAuthenticatorImpl::~InternalAuthenticatorImpl() = default;
void InternalAuthenticatorImpl::SetEffectiveOrigin(const url::Origin& origin) {
effective_origin_ = url::Origin(origin);
DCHECK(!effective_origin_.opaque());
}
void InternalAuthenticatorImpl::SetPaymentOptions(
blink::mojom::PaymentOptionsPtr payment) {
payment_ = std::move(payment);
}
void InternalAuthenticatorImpl::MakeCredential(
blink::mojom::PublicKeyCredentialCreationOptionsPtr options,
blink::mojom::Authenticator::MakeCredentialCallback callback) {
authenticator_common_->MakeCredential(effective_origin_, std::move(options),
std::move(callback));
}
void InternalAuthenticatorImpl::GetAssertion(
blink::mojom::PublicKeyCredentialRequestOptionsPtr options,
GetAssertionCallback callback) {
authenticator_common_->GetCredential(
effective_origin_, std::move(options), std::move(payment_),
base::BindOnce(
[](GetAssertionCallback get_assertion_callback,
blink::mojom::GetCredentialResponsePtr response) {
if (response.is_null() || !response->is_get_assertion_response()) {
return;
}
auto assertion = std::move(response->get_get_assertion_response());
std::move(get_assertion_callback)
.Run(assertion->status, std::move(assertion->credential),
std::move(assertion->dom_exception_details));
},
std::move(callback)));
}
void InternalAuthenticatorImpl::IsUserVerifyingPlatformAuthenticatorAvailable(
blink::mojom::Authenticator::
IsUserVerifyingPlatformAuthenticatorAvailableCallback callback) {
authenticator_common_->IsUserVerifyingPlatformAuthenticatorAvailable(
effective_origin_, std::move(callback));
}
bool InternalAuthenticatorImpl::IsGetMatchingCredentialIdsSupported() {
// TODO(crbug.com/40868539): Not yet supported on any desktop platform.
return false;
}
void InternalAuthenticatorImpl::GetMatchingCredentialIds(
const std::string& relying_party_id,
const std::vector<std::vector<uint8_t>>& credential_ids,
bool require_third_party_payment_bit,
webauthn::GetMatchingCredentialIdsCallback callback) {
// Not yet supported on any desktop platform.
NOTREACHED();
}
void InternalAuthenticatorImpl::Cancel() {
authenticator_common_->Cancel();
}
content::RenderFrameHost* InternalAuthenticatorImpl::GetRenderFrameHost() {
return authenticator_common_->GetRenderFrameHost();
}
void InternalAuthenticatorImpl::DidFinishNavigation(
NavigationHandle* navigation_handle) {
// If the RenderFrameHost itself is navigated then this function will cause
// request state to be cleaned up. It's also possible for a navigation in the
// same frame to use a fresh RenderFrameHost. In this case,
// |render_frame_host_->IsCurrent()| will start returning false, causing all
// focus checks to fail if any Mojo requests are made in that state.
if (!navigation_handle->HasCommitted() ||
navigation_handle->IsSameDocument() ||
navigation_handle->GetRenderFrameHost() != GetRenderFrameHost()) {
return;
}
authenticator_common_->Cleanup();
}
} // namespace content
|