web-dev-qa-db-fra.com

Identité .NET Core en tant que registre d'annulation de l'interface utilisateur

Je souhaite annuler l'option "S'inscrire" dans une application .NET Core 2.1 + Identity as UI.

Je peux bien sûr simplement retirer le bouton de la page, la question est - est-ce sûr?

Sinon, quelles sont mes autres options? dois-je utiliser un échafaudage pour générer le code d'enregistrement puis le désactiver là-bas?

(il en va de même pour SetPassword, etc.)

Merci

22
kofifus

Malheureusement, les deux autres réponses sont incorrectes - la question se réfère en fait à la nouvelle extension AddDefaultIdentity () qui utilise les pages Razor pour servir une interface utilisateur par défaut. La réponse qui résout ce problème ne supprimera pas la fonctionnalité d'enregistrement comme demandé dans la question.

Contexte

AddDefaultIdentity fonctionne de manière similaire à AddIdentity mais inclut également un appel à AddDefaultUI qui donne à votre application l'accès aux nouvelles vues du rasoir Identity (actuellement 28 d'entre elles), elles se trouvent dans une nouvelle bibliothèque de classes de rasoir. Notez que ce n'est pas la seule différence entre AddDefaultIdentity et AddIdentity (voir plus loin).

Pour modifier les vues par défaut, vous devez remplacer ("échafauder") les vues de votre projet et vous pouvez ensuite les modifier. Si vous ne remplacez pas les vues, ou si vous les remplacez puis supprimez les fichiers cshtml, vous reviendrez simplement aux versions par défaut de l'interface utilisateur! Même si vous supprimez les liens vers par exemple vous inscrire, l'utilisateur peut toujours accéder à la vue de registre par défaut s'il devine l'URL.

Option 1 - Remplacer les vues

Si vous souhaitez conserver certaines des vues par défaut et en modifier ou en supprimer d'autres, vous pouvez remplacer les vues comme suit ( à partir de ce document ):

  1. Faites un clic droit sur votre projet> Ajouter> Nouvel élément échafaudé
  2. Dans le volet gauche de la boîte de dialogue Ajouter un échafaudage, sélectionnez Identité> Ajouter
  3. Dans la boîte de dialogue Ajouter une identité, sélectionnez les options souhaitées

Vous pouvez maintenant soit simplement changer l'apparence et la fonctionnalité de la vue que vous avez remplacée, soit la "supprimer", vous pouvez la renvoyer un 404 ou la rediriger ailleurs. Si vous supprimez cette vue remplacée, l'interface utilisateur par défaut reviendra!

Cette approche peut devenir rapidement désordonnée si vous souhaitez remplacer toutes les vues.

Option 2 - Ne pas ajouter d'interface utilisateur par défaut

Une autre option consiste à revenir à l'ancienne façon d'ajouter une identité qui ne fait pas appel à AddDefaultUI, l'inconvénient est que vous devrez ajouter toutes les vues vous-même. Vous pouvez le faire comme suit ( à partir de ce document - bien qu'ignorer la première ligne sur la substitution de toutes les vues, qui s'applique à l'option 1 ci-dessus):

//remove this: services.AddDefaultIdentity<IdentityUser>()
//use this instead to get the Identity basics without any default UI:
services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

//this assumes you want to continue using razor views for your identity UI
//it specifies areas can be used with razor pages and then adds an 
//authorize filter with a default policy for the folder /Account/Manage and
//the page /Account/Logout.cshtml (both of which live in Areas/Identity/Pages)
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
    .AddRazorPagesOptions(options =>
    {
        options.AllowAreas = true;
        options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
        options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
    });

//configures the application cookie to redirect on challenge, etc.
services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = $"/Identity/Account/Login";
    options.LogoutPath = $"/Identity/Account/Logout";
    options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});

//configures an email sender for e.g. password resets
services.AddSingleton<IEmailSender, EmailSender>();

Notez que je ne suis pas convaincu à 100% que cette deuxième approche soit sans problème non plus, comme mentionné ci-dessus, il existe d'autres différences entre AddDefaultIdentity et AddIdentity. Par exemple, ce dernier ajoute le service RoleManager, contrairement au premier. De plus, il n'est pas clair pour moi si ces deux approches seront soutenues et maintenues également à l'avenir.

En cas de doute sur ce que font les options ci-dessus (et si vous avez quelques heures à tuer), vous pouvez consulter la source de AddDefaultIdentity (qui appelle également AddIdentityCookies et - AddIdentityCore ) par rapport à l'ancien AddIdentity .

Option 3 - Approche hybride

La meilleure option actuellement est probablement de combiner les 2 précédents, de la manière suivante:

  1. Configurer votre projet pour utiliser l'identité par défaut
  2. Échafaudez uniquement les vues que vous souhaitez inclure et modifiez-les en conséquence
  3. Basculez vers l'ancien appel AddIdentity et incluez les options de rasoir comme indiqué dans l'option 2 (en ajustant si nécessaire en fonction des vues que vous avez incluses

Vous n'avez maintenant que les vues souhaitées et elles sont basées sur les implémentations par défaut, ce qui signifie que la plupart du travail est effectué pour vous pour ces vues.

7
Matt

Pour les pages Web ASP.NET, il s'agit d'un module complémentaire pour la réponse précédente pour inclure les pages Web de rasoir ASP.Net. Je les ai séparés comme si quelqu'un devait en avoir besoin et ne pas se confondre. Les pages Web sont différentes car elles incluent du code comme les formulaires Web.

Vous allez d'abord modifier les pages> _LoginPartial.cshtml

Supprimer la ligne <li><a asp-page="/Account/Register">Register</a></li>

Ensuite, modifiez Pages> Compte> Login.cshtml. Supprimez les éléments suivants:

                <div class="form-group">
                <p>
                    <a asp-page="./ForgotPassword">Forgot your password?</a>
                </p>
                <p>
                    <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
                </p>
            </div>

Supprimez également:

<div class="col-md-6 col-md-offset-2">
    <section>
        <h4>Use another service to log in.</h4>
        <hr />
        @{
            if ((Model.ExternalLogins?.Count ?? 0) == 0)
            {
                <div>
                    <p>
                        There are no external authentication services configured. See <a href="https://go.Microsoft.com/fwlink/?LinkID=532715">this article</a>
                        for details on setting up this ASP.NET application to support logging in via external services.
                    </p>
                </div>
            }
            else
            {
                <form asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
                    <div>
                        <p>
                            @foreach (var provider in Model.ExternalLogins)
                            {
                                <button type="submit" class="btn btn-default" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
                            }
                        </p>
                    </div>
                </form>
            }
        }
    </section>
</div>

Modifiez maintenant le code derrière Login.cshtml.cs

Retirer:

public IList<AuthenticationScheme> ExternalLogins { get; set; }

Supprimer également:

// Clear the existing external cookie to ensure a clean login process
        await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

        ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

Modifier les pages> Compte> Gérer> _ManageNav.cshtml

Retirer:

    @if (hasExternalLogins)
{
    <li class="@ManageNavPages.ExternalLoginsNavClass(ViewContext)"><a asp-page="./ExternalLogins">External logins</a></li>
}

Ensuite, nous supprimerons les fichiers suivants du répertoire Pages> Compte:

  • ExternalLogin.cshtml
  • ForgotPassword.cshtml
  • ForgotPasswordConfirmation.cshtml
  • Register.cshtml
  • ResetPassword.cshtml
  • ResetPasswordConfirmation.cshtml

Supprimez les fichiers suivants du répertoire Pages> Compte> Gérer:

  • ExternalLogin.cshtml
6
pool pro

Je suppose que vous parlez d'une application Web Model-View-Controller. Je peux vous dire qu'il n'est pas sûr de simplement supprimer le bouton ou même les vues pour cela.

Je suppose également que vous souhaitez supprimer la connexion tierce qui créerait également un utilisateur enregistré.

Je ferais ce qui suit:

Dans votre contrôleur de compte, supprimez les éléments suivants

[HttpGet]
    [AllowAnonymous]
    public IActionResult Register(string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        return View();
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await _userManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                _logger.LogInformation("User created a new account with password.");

                var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
                await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);

                await _signInManager.SignInAsync(user, isPersistent: false);
                _logger.LogInformation("User created a new account with password.");
                return RedirectToLocal(returnUrl);
            }
            AddErrors(result);
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

Toujours dans le contrôleur de compte plus bas, supprimez les éléments suivants:

[HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public IActionResult ExternalLogin(string provider, string returnUrl = null)
    {
        // Request a redirect to the external login provider.
        var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Account", new { returnUrl });
        var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
        return Challenge(properties, provider);
    }

    [HttpGet]
    [AllowAnonymous]
    public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
    {
        if (remoteError != null)
        {
            ErrorMessage = $"Error from external provider: {remoteError}";
            return RedirectToAction(nameof(Login));
        }
        var info = await _signInManager.GetExternalLoginInfoAsync();
        if (info == null)
        {
            return RedirectToAction(nameof(Login));
        }

        // Sign in the user with this external login provider if the user already has a login.
        var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider);
            return RedirectToLocal(returnUrl);
        }
        if (result.IsLockedOut)
        {
            return RedirectToAction(nameof(Lockout));
        }
        else
        {
            // If the user does not have an account, then ask the user to create an account.
            ViewData["ReturnUrl"] = returnUrl;
            ViewData["LoginProvider"] = info.LoginProvider;
            var email = info.Principal.FindFirstValue(ClaimTypes.Email);
            return View("ExternalLogin", new ExternalLoginViewModel { Email = email });
        }
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ExternalLoginConfirmation(ExternalLoginViewModel model, string returnUrl = null)
    {
        if (ModelState.IsValid)
        {
            // Get the information about the user from the external login provider
            var info = await _signInManager.GetExternalLoginInfoAsync();
            if (info == null)
            {
                throw new ApplicationException("Error loading external login information during confirmation.");
            }
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await _userManager.CreateAsync(user);
            if (result.Succeeded)
            {
                result = await _userManager.AddLoginAsync(user, info);
                if (result.Succeeded)
                {
                    await _signInManager.SignInAsync(user, isPersistent: false);
                    _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
                    return RedirectToLocal(returnUrl);
                }
            }
            AddErrors(result);
        }

        ViewData["ReturnUrl"] = returnUrl;
        return View(nameof(ExternalLogin), model);
    }

supprimer également

[HttpGet]
    [AllowAnonymous]
    public IActionResult ForgotPassword()
    {
        return View();
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = await _userManager.FindByEmailAsync(model.Email);
            if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))
            {
                // Don't reveal that the user does not exist or is not confirmed
                return RedirectToAction(nameof(ForgotPasswordConfirmation));
            }

            // For more information on how to enable account confirmation and password reset please
            // visit https://go.Microsoft.com/fwlink/?LinkID=532713
            var code = await _userManager.GeneratePasswordResetTokenAsync(user);
            var callbackUrl = Url.ResetPasswordCallbackLink(user.Id, code, Request.Scheme);
            await _emailSender.SendEmailAsync(model.Email, "Reset Password",
               $"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>");
            return RedirectToAction(nameof(ForgotPasswordConfirmation));
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

    [HttpGet]
    [AllowAnonymous]
    public IActionResult ForgotPasswordConfirmation()
    {
        return View();
    }

    [HttpGet]
    [AllowAnonymous]
    public IActionResult ResetPassword(string code = null)
    {
        if (code == null)
        {
            throw new ApplicationException("A code must be supplied for password reset.");
        }
        var model = new ResetPasswordViewModel { Code = code };
        return View(model);
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ResetPassword(ResetPasswordViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }
        var user = await _userManager.FindByEmailAsync(model.Email);
        if (user == null)
        {
            // Don't reveal that the user does not exist
            return RedirectToAction(nameof(ResetPasswordConfirmation));
        }
        var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);
        if (result.Succeeded)
        {
            return RedirectToAction(nameof(ResetPasswordConfirmation));
        }
        AddErrors(result);
        return View();
    }

    [HttpGet]
    [AllowAnonymous]
    public IActionResult ResetPasswordConfirmation()
    {
        return View();
    }

Maintenant, sous Modèles, vous pouvez supprimer les fichiers suivants:

  • ExternalLoginViewModel
  • ForgotPasswordViewModel
  • RegisterViewModel
  • ResetPasswordViewModel

Sous Vues, ​​je supprimerais:

  • Confirmez votre e-mail
  • ExternalLogin
  • Mot de passe oublié
  • ForgotPasswordConfirmation
  • S'inscrire
  • Réinitialiser le mot de passe
  • ResetPasswordConfirmation

Également sous Vues du compte, modifiez Login.cshtml et supprimez les éléments suivants:

                <div class="form-group">
                <p>
                    <a asp-page="./ForgotPassword">Forgot your password?</a>
                </p>
                <p>
                    <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
                </p>
            </div>

Supprimez également:

<div class="col-md-6 col-md-offset-2">
    <section>
        <h4>Use another service to log in.</h4>
        <hr />
        @{
            if ((Model.ExternalLogins?.Count ?? 0) == 0)
            {
                <div>
                    <p>
                        There are no external authentication services configured. See <a href="https://go.Microsoft.com/fwlink/?LinkID=532715">this article</a>
                        for details on setting up this ASP.NET application to support logging in via external services.
                    </p>
                </div>
            }
            else
            {
                <form asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
                    <div>
                        <p>
                            @foreach (var provider in Model.ExternalLogins)
                            {
                                <button type="submit" class="btn btn-default" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
                            }
                        </p>
                    </div>
                </form>
            }
        }
    </section>
</div>

Maintenant, sous vos vues partagées, ouvrez _LoginPartial.cshtml et supprimez les éléments suivants:

<li><a asp-area="" asp-controller="Account" asp-action="Register">Register</a></li>

Sous Gérer les vues _ManageNav.cshtml, supprimez les éléments suivants:

    @if (hasExternalLogins)
{
    <li class="@ManageNavPages.ExternalLoginsNavClass(ViewContext)"><a asp-action="ExternalLogins">External logins</a></li>
}

Maintenant, même si vous allez à l'URL yourapp.com/Account/Register, vous obtiendrez une page 404.

J'espère que cela t'aides.

2
pool pro