web-dev-qa-db-fra.com

Comment transmettre returnUrl à la page de connexion dans l'application Blazor Server?

J'ai une application serveur Blazor simple, avec l'identité utilisant l'authentification individuelle. J'ai créé l'application à partir de la norme VS 2019 dotnet new modèle.

Dans certaines parties de l'application, je voudrais diriger l'utilisateur vers la page de connexion, tout en lui passant un paramètre returnUrl. J'ai essayé les variantes de code suivantes pour passer ce paramètre ( counter est la page à laquelle je veux revenir):

NavigationManager.NavigateTo("Identity/Account/Login?returnUrl=counter", forceLoad: true);
NavigationManager.NavigateTo("Identity/Account/Login?returnUrl='/counter'", forceLoad: true);
NavigationManager.NavigateTo("Identity/Account/Login?returnUrl='./counter'", forceLoad: true);
NavigationManager.NavigateTo("Identity/Account/Login?returnUrl='~/counter'", forceLoad: true);

Cependant, avec tout cela, j'obtiens un message d'erreur indiquant que "l'URI n'est pas local". Le message d'erreur est:

"InvalidOperationException: l'URL fournie n'est pas locale. Une URL avec un chemin absolu est considérée comme locale si elle n'a pas de partie hôte/autorité. Les URL utilisant des chemins virtuels ('~ /') sont également locales."

Quelqu'un peut-il suggérer le formatage approprié du paramètre returnUrl dans cette situation? Pour plus d'informations, je suis les suggestions de @iambacon (merci à Colin!), Dans son article de blog sur la redirection vers la page de connexion pour les applications Blazor. C'est un excellent article et accomplit une partie de ce que je veux: rediriger vers la connexion lorsque l'utilisateur n'est pas authentifié. Je voudrais simplement ajouter la fonctionnalité supplémentaire de revenir à cette URL une fois l'authentification terminée.

4
Randy Gamage

"L'URI n'est pas locale".

Pour résoudre ce problème ...

Procédez comme suit:

  1. Créez dans le dossier Pages un composant nommé RedirectToLogin avec le code suivant:

RedirectToLogin.razor

@inject NavigationManager NavigationManager

@code{
  [Parameter]
  public string ReturnUrl {get; set;}
  protected override  void OnInitialized()
  {
        ReturnUrl = "~/" + ReturnUrl;
        NavigationManager.NavigateTo($"Identity/Account/Login?returnUrl= 
       {ReturnUrl}", forceLoad:true);
  }
}

Ouvrez App.razor et ajoutez le code suivant à AuthorizeRouteView.NotAuthorized

<NotAuthorized>
@{
    var returnUrl = 
    NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
    <RedirectToLogin ReturnUrl="@returnUrl"/>

 }
</NotAuthorized>

Injectez également le NavigationManager en haut du composant App comme ceci:

@inject NavigationManager NavigationManager

Pour tester cela, en haut de la page du composant Fetchdata (ou Counter si vous le souhaitez), ajoutez la directive @attribute pour l'attribut Authorize, comme ceci: @attribute [Authorize] Lorsqu'un utilisateur non authentifié tente d'accéder à la page Fetchdata, la propriété de délégué AuthorizeRouteView.NotAuthorized est exécutée et le composant RedirectToLogin est rendu avec son attribut de paramètre défini sur l'URL actuelle.

Mettre à jour

L'ajout suivant consiste à ajouter des boutons de connexion et de déconnexion à votre application ...

  1. Créez un composant nommé LoginDisplay.razor dans le dossier Shared et ajoutez-y le code suivant:
     <AuthorizeView>
      <Authorized>
        <a href="Identity/Account/Manage">Hello, 
        @context.User.Identity.Name!</a>
        <form method="post" action="Identity/Account/LogOut">
            <button type="submit" class="nav-link btn btn-link">Log 
        out</button>
        </form>
      </Authorized>
         <NotAuthorized>
            <a href="Identity/Account/Register">Register</a>
            <a href="Identity/Account/Login">Log in</a>
         </NotAuthorized>
      </AuthorizeView>

Dans le composant MainLayout, ajoutez l'élément LoginDisplay comme suit:

<div class="top-row px-4 auth">
    <LoginDisplay />
    <a href="https://docs.Microsoft.com/aspnet/" 
         target="_blank">About</a>
</div>

Exécutez votre application et testez le bouton de connexion et de déconnexion ...

5
enet