Udostępnij za pośrednictwem


Włączanie generowania kodu QR dla aplikacji uwierzytelniania TOTP w aplikacji internetowej platformy ASP.NET Core Blazor

W tym artykule wyjaśniono, jak skonfigurować aplikację internetową platformy ASP.NET Core Blazor przy użyciu generowania kodu QR dla aplikacji uwierzytelniającego TOTP.

Aby zapoznać się z wprowadzeniem do uwierzytelniania dwuskładnikowego (2FA) z aplikacjami uwierzytelniania przy użyciu jednorazowego algorytmu haseł (TOTP) opartego na czasie, zobacz Włączanie generowania kodu QR dla aplikacji uwierzytelniania TOTP w ASP.NET Core.

Tworzenie szkieletu składnika Enable Authenticator w aplikacji

Postępuj zgodnie ze wskazówkami w artykule Tworzenie szkieletu Identity w projektach ASP.NET Core w celu tworzenia Pages\Manage\EnableAuthenticator szkieletu w aplikacji.

Uwaga

Mimo że w tym przykładzie EnableAuthenticator wybrano tylko składnik do tworzenia szkieletów, szkielet obecnie dodaje wszystkie Identity składniki do aplikacji. Ponadto wyjątki mogą być zgłaszane podczas procesu tworzenia szkieletu w aplikacji. Jeśli wystąpią wyjątki podczas migracji bazy danych, zatrzymaj aplikację i uruchom ponownie aplikację w każdym wyjątku. Aby uzyskać więcej informacji, zobacz Wyjątki tworzenia szkieletów dla Blazor aplikacji internetowej (dotnet/Scaffolding #2694).

Bądź cierpliwy podczas wykonywania migracji. W zależności od szybkości systemu ukończenie migracji bazy danych może potrwać do minuty lub dwóch.

Aby uzyskać więcej informacji, zobacz Szkielet Identity w projektach ASP.NET Core. Aby uzyskać wskazówki dotyczące korzystania z interfejsu wiersza polecenia platformy .NET zamiast programu Visual Studio, zobacz dotnet aspnet-codegenerator polecenia.

Dodawanie kodów QR do strony konfiguracji 2FA

Te instrukcje korzystają z qrcode.js Shim Sangmin: Generator QRCode między przeglądarkami dla języka JavaScript (davidshimjs/qrcodejsrepozytorium GitHub).

Pobierz bibliotekę qrcode.min.js do wwwroot folderu projektu serwera rozwiązania. Biblioteka nie ma żadnych zależności.

W składniku App (Components/App.razor) umieść odwołanie do skryptu biblioteki po Blazortagu <script>:

<script src="qrcode.min.js"></script>

Składnik EnableAuthenticator , który jest częścią systemu kodu QR w aplikacji i wyświetla kod QR dla użytkowników, przyjmuje statyczne renderowanie po stronie serwera (statyczne SSR) z ulepszoną nawigacją. W związku z tym normalne skrypty nie mogą być wykonywane, gdy składnik ładuje lub aktualizuje w ramach rozszerzonej nawigacji. Dodatkowe kroki są wymagane do wyzwolenia kodu QR w celu załadowania w interfejsie użytkownika po załadowaniu strony. Aby można było załadować kod QR, przyjmuje się podejście opisane w ASP.NET Core Blazor JavaScript ze statycznym renderowaniem po stronie serwera (statycznym usługą SSR).

Dodaj następujący inicjator języka JavaScript do folderu projektu wwwroot serwera. Symbol {NAME} zastępczy musi być nazwą zestawu aplikacji, aby Blazor można było automatycznie zlokalizować i załadować plik. Jeśli nazwa zestawu aplikacji serwera to BlazorSample, plik ma nazwę BlazorSample.lib.module.js.

wwwroot/{NAME}.lib.module.js:

const pageScriptInfoBySrc = new Map();

function registerPageScriptElement(src) {
  if (!src) {
    throw new Error('Must provide a non-empty value for the "src" attribute.');
  }

  let pageScriptInfo = pageScriptInfoBySrc.get(src);

  if (pageScriptInfo) {
    pageScriptInfo.referenceCount++;
  } else {
    pageScriptInfo = { referenceCount: 1, module: null };
    pageScriptInfoBySrc.set(src, pageScriptInfo);
    initializePageScriptModule(src, pageScriptInfo);
  }
}

function unregisterPageScriptElement(src) {
  if (!src) {
    return;
  }

  const pageScriptInfo = pageScriptInfoBySrc.get(src);
  
  if (!pageScriptInfo) {
    return;
  }

  pageScriptInfo.referenceCount--;
}

async function initializePageScriptModule(src, pageScriptInfo) {
  if (src.startsWith("./")) {
    src = new URL(src.substr(2), document.baseURI).toString();
  }

  const module = await import(src);

  if (pageScriptInfo.referenceCount <= 0) {
    return;
  }

  pageScriptInfo.module = module;
  module.onLoad?.();
  module.onUpdate?.();
}

function onEnhancedLoad() {
  for (const [src, { module, referenceCount }] of pageScriptInfoBySrc) {
    if (referenceCount <= 0) {
      module?.onDispose?.();
      pageScriptInfoBySrc.delete(src);
    }
  }

  for (const { module } of pageScriptInfoBySrc.values()) {
    module?.onUpdate?.();
  }
}

export function afterWebStarted(blazor) {
  customElements.define('page-script', class extends HTMLElement {
    static observedAttributes = ['src'];

    attributeChangedCallback(name, oldValue, newValue) {
      if (name !== 'src') {
        return;
      }

      this.src = newValue;
      unregisterPageScriptElement(oldValue);
      registerPageScriptElement(newValue);
    }

    disconnectedCallback() {
      unregisterPageScriptElement(this.src);
    }
  });

  blazor.addEventListener('enhancedload', onEnhancedLoad);
}

Dodaj następujący składnik udostępniony PageScript do aplikacji serwera.

Components/PageScript.razor:

<page-script src="@Src"></page-script>

@code {
    [Parameter]
    [EditorRequired]
    public string Src { get; set; } = default!;
}

Dodaj następujący skomponowany JS plik dla EnableAuthenticator składnika, który znajduje się w Components/Account/Pages/Manage/EnableAuthenticator.razorlokalizacji . Funkcja onLoad tworzy kod QR z biblioteką Sangmin qrcode.js przy użyciu identyfikatora URI kodu QR wygenerowanego przez metodę GenerateQrCodeUri w bloku składnika @code .

Components/Account/Pages/Manage/EnableAuthenticator.razor.js:

export function onLoad() {
  const uri = document.getElementById('qrCodeData').getAttribute('data-url');
  new QRCode(document.getElementById('qrCode'), uri);
}

<PageTitle> W obszarze składnika dodaj PageScript składnik EnableAuthenticator ze ścieżką do skomponowanego JS pliku:

<PageScript Src="./Components/Account/Pages/Manage/EnableAuthenticator.razor.js" />

Uwaga

Alternatywą dla korzystania z podejścia ze PageScript składnikiem jest użycie odbiornika zdarzeń (blazor.addEventListener("enhancedload", {CALLBACK})) zarejestrowanego w inicjatorzeafterWebStartedJS do nasłuchiwania aktualizacji stron spowodowanych przez rozszerzoną nawigację. Wywołanie zwrotne ({CALLBACK} symbol zastępczy) wykonuje logikę inicjowania kodu QR.

Przy użyciu metody wywołania zwrotnego z enhancedloadprogramem kod jest wykonywany dla każdej rozszerzonej nawigacji, nawet jeśli kod <div> QR nie jest renderowany. Dlatego należy dodać dodatkowy kod, aby sprawdzić obecność <div> obiektu przed wykonaniem kodu, który dodaje kod QR.

<div> Usuń element zawierający instrukcje kodu QR:

- <div class="alert alert-info">
-     Learn how to <a href="https://go.microsoft.com/fwlink/?Linkid=852423">enable 
-     QR code generation</a>.
- </div>

Znajdź dwa <div> elementy, w których powinien zostać wyświetlony kod QR i gdzie dane kodu QR są przechowywane na stronie.

Wprowadź następujące zmiany:

  • Dla pustego <div>elementu nadaj elementowi qrCodewartość id .
  • <div> Dla atrybutu za pomocą atrybutu data-url nadaj elementowi wartość idqrCodeData.
- <div></div>
- <div data-url="@authenticatorUri"></div>
+ <div id="qrCode"></div>
+ <div id="qrCodeData" data-url="@authenticatorUri"></div>

Zmień nazwę witryny w GenerateQrCodeUri metodzie EnableAuthenticator składnika. Domyślna wartość to Microsoft.AspNetCore.Identity.UI. Zmień wartość na znaczącą nazwę witryny, którą użytkownicy mogą łatwo zidentyfikować w swojej aplikacji wystawcy uwierzytelniania wraz z innymi kodami QR dla innych aplikacji. Pozostaw zakodowany adres URL wartości. Deweloperzy zazwyczaj ustawiają nazwę witryny zgodną z nazwą firmy. Przykłady: Yahoo, Amazon, Etsy, Microsoft, Zoho.

W poniższym przykładzie {SITE NAME} symbol zastępczy to miejsce, w którym nazwa witryny (firmy):

private string GenerateQrCodeUri(string email, string unformattedKey)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        AuthenticatorUriFormat,
-       UrlEncoder.Encode("Microsoft.AspNetCore.Identity.UI"),
+       UrlEncoder.Encode("{SITE NAME}"),
        UrlEncoder.Encode(email),
        unformattedKey);
}

Uruchom aplikację i upewnij się, że kod QR jest skanowany i czy kod jest weryfikowany.

EnableAuthenticator składnik w źródle referencyjnym

Składnik EnableAuthenticator można sprawdzić w źródle referencyjnym:

EnableAuthenticator składnik w źródle referencyjnym

Uwaga

Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Dodatkowe zasoby